this指针和重构
this指针
this指针用来指向当前对象
class Point { public: Point(int ix = 0, int iy = 0) :_ix(ix) , _iy(iy) { cout << "Have done Create" << ' '<<_ix<<' '<<_iy<<endl; } void print() { cout<<this->_ix<<' '<<this->_iy<<endl; } private: int _ix; int _iy; };
|
每一个非静态修饰的成员函数都有隐含的this指针(为什么静态没有,后文会说明)
this指针会作为函数成员的一个隐藏的第一个参数,在编译时会自动填充,不需要我们自己填补(会报错)
Point p1(1, 1); p1.print();
|
operator重构
重构(我自己定义的词,根据重载推演的,准确翻译叫什么我也不知道)就是对一个已定义的函数,操作运算符重新定义,重新构造一遍
重构对当前类赋值运算符重构(即重构深拷贝)
class Point { public: Point(int ix = 0, int iy = 0) :_ix(ix) , _iy(iy) { cout << "Have done Create" << ' '<<_ix<<' '<<_iy<<endl; } Point(const Point& p) :_ix(p._ix) ,_iy(p._iy) { cout << "Have done Copy" << endl; } Point& operator = (const Point& p) { _ix = p._ix; _iy = p._iy;
cout << "Have done operator=" << endl; return *this; } void print() { cout << this->_ix << ' ' << this->_iy << endl; }
private: int _ix; int _iy; };
|
深拷贝的两种写法
Point p2(2,2);
p2 = p1; p2.operator = (p1);
|
完整代码
#include <iostream>
using std::cout; using std::endl;
class Point { public: Point(int ix = 0, int iy = 0) :_ix(ix) , _iy(iy) { cout << "Have done Create" << ' '<<_ix<<' '<<_iy<<endl; } Point(const Point& p) :_ix(p._ix) ,_iy(p._iy) { cout << "Have done Copy" << endl; } Point& operator = (const Point& p) { _ix = p._ix; _iy = p._iy;
cout << "Have done operator=" << endl; return *this; } void print() { cout << this->_ix << ' ' << this->_iy << endl; }
private: int _ix; int _iy; }; void test0() { Point p1(1, 1);
p1.print();
Point p2(2, 2); p2 = p1; p2.operator = (p1); } int main() { test0(); return 0; }
|
数据成员修饰
const数据成员
const初始化
一般在定义构造函数的时候,通常去初始化一堆数据成员,防止运行出错
Point(int ix,int iy,int iz) :_ix(ix) ,_iy(iy) ,_iz(iz) { cout << "Have done structure" << endl; }
|
可以在private内部 声明数据成员时用const修饰
const int _ix = 10;
const int _iy = 10;
|
此时即使不使用初始化列表(有参构造函数),对象创建时他的数据成员也已经被初始化了
class Point { public:
Point() = default;
Point(const int& ix,const int& iy) :_ix(ix) ,_iy(iy) { cout << "Have done structure" << endl; } void print() { cout << _ix << ' ' << _iy << endl; } private: const int _ix = 10; const int _iy = 10; };
int main() { Point p; p.Print(); Point p1(1, 2); p1.print(); const Point p2(1, 2); p2.print(); }
|
输出结果
···
10 10
Have done structure
1 2
Have done structure
1 2
···
const成员函数
const修饰的成员函数只能读取数据成员不能进行修改,不允许在内部改变
const修饰对象只能调用const成员函数
非const修饰的对象可以调用const成员函数,也可以调用非const成员函数
const成员函数形式
void print() const { cout<<_ix<<' '<<_iy<<endl; }
|
const在对象应用的完整代码
#include <iostream>
using std::cout; using std::endl;
class Point { public:
Point() = default;
Point(const int& ix,const int& iy) :_ix(ix) ,_iy(iy) { cout << "Have done structure" << endl; }
void print() const { cout << _ix << ' ' << _iy << endl; }
void print() { cout << _ix << ' ' << _iy << endl; } private: const int _ix = 10; const int _iy = 10; }; class Line { public: Line(int x1, int y1, int x2, int y2) :_pt1(Point(x1,y1)) ,_pt2(Point(x2,y2)) { cout << "Line(x1,y1,x2,y2)" << endl; } void LinePrint() { _pt1.print(); _pt2.print(); } private: Point _pt1; Point _pt2; }; void test0() { Point p; p.print(); Point p1(1, 2); p1.print(); const Point p2(1, 2); p2.print();
Line l1(1, 2, 3, 4); l1.LinePrint(); } int main() { test0();
return 0; }
|
static数据成员
static修饰数据成员
static修饰的数据成员被整个类所有对象所共享
static数据成员分布在全局静态区,不占用对象的存储空间
static数据成员需要在类之外,全局区初始化
class Computer { public: private: char* _name; int _price; static double TotalPrice; };
double Computer::_TotalPrice = 0;
int main() { return 0; }
|
假设有Computer类,有若干Computer对象,求所有对象的总价,就可以用static修饰的数据成员去求得
静态数据成员需要注意的点
如果不存在静态数据成员,类的定义可以如下写
class Computer { public: Computer(const char* brand, const int& price) :_brand(new char[strlen(brand) + 1]()) , _price(price) { strcpy(_brand, brand); cout << "Have done structure!" << endl; } void release() { delete[] _brand; _brand = nullptr; } ~Computer() { if (_brand) release(); cout << "Have do ne Delete" << endl;
}
void swap(Computer& p) { std::swap(this->_brand, p._brand); std::swap(this->_price, p._price); }
Computer(const Computer& p) :_brand(new char[strlen(p._brand) + 1]()) , _price(p._price) { strcpy(_brand, p._brand); } Computer& operator = (const Computer& p) { if (this == &p) return *this;
Computer tmp(p._brand, p._price);
swap(tmp);
return *this; }
void print() { cout << _brand << ' '; cout << _price << endl; }
private: char* _brand; int _price; };
|
当有了静态数据成员TotalPrice时,函数构造,拷贝,折构时都需要对该变量特殊处理
class Computer { public: Computer(const char* brand, const int& price) :_brand(new char[strlen(brand) + 1]()) , _price(price) { strcpy(_brand, brand); _TotalPrice += _price; cout << "Have done structure!" << endl; } void release() { delete[] _brand; _brand = nullptr; } ~Computer() { if (_brand) release(); _TotalPrice -= _price; cout << "Have do ne Delete" << endl;
}
void swap(Computer& p) { std::swap(this->_brand, p._brand); std::swap(this->_price, p._price); }
Computer(const Computer& p) :_brand(new char[strlen(p._brand) + 1]()) , _price(p._price) { _TotalPrice += _price; strcpy(_brand, p._brand); } Computer& operator = (const Computer& p) { if (this == &p) return *this;
_TotalPrice -= _price;
Computer tmp(p._brand, p._price);
swap(tmp);
_TotalPrice += _price;
return *this; }
void print() { cout << _brand << ' '; cout << _price << endl; }
private: char* _brand; int _price; static double _TotalPrice; };
|
静态成员函数
1.静态函数成员内部只能访问静态数据成员和静态函数成员
2.不能访问非静态数据成员和函数成员
3.静态成员函数内部没有隐含的this指针(即不能指向非静态数据成员)
静态函数成员形式
static void printTotal() { cout << _TotalPrice << endl; }
|
static在对象应用中的完整代码
#include <iostream>
using std::cout; using std::endl;
class Computer { public: Computer(const char* brand, const int& price) :_brand(new char[strlen(brand) + 1]()) , _price(price) { strcpy(_brand, brand); _TotalPrice += _price; cout << "Have done structure!" << endl; } void release() { delete[] _brand; _brand = nullptr; } ~Computer() { if (_brand) release(); _TotalPrice -= _price; cout << "Have do ne Delete" << endl;
}
void swap(Computer& p) { std::swap(this->_brand, p._brand); std::swap(this->_price, p._price); }
Computer(const Computer& p) :_brand(new char[strlen(p._brand) + 1]()) , _price(p._price) { _TotalPrice += _price; strcpy(_brand, p._brand); } Computer& operator = (const Computer& p) { if (this == &p) return *this;
_TotalPrice -= _price;
Computer tmp(p._brand, p._price);
swap(tmp);
_TotalPrice += _price;
return *this; }
void print() { cout << _brand << ' '; cout << _price << endl; }
static void printTotal() { cout << _TotalPrice << endl; }
private: char* _brand; int _price; static double _TotalPrice; };
double Computer::_TotalPrice = 0;
void copy(Computer p) { p.print(); p.printTotal(); } void test1() { Computer p1("abc", 4999); Computer p2 = p1;
p1.print(); p1.printTotal();
copy(p2);
p1.print(); p1.printTotal();
Computer::printTotal(); } int main() { test1();
return 0; }
|
单例模式
特点:一个类只能生成一个对象,且是唯一的对象
单例模式的定义方法
1.将构造函数私有化
创建的对象就既不能是栈对象,也不能是全局/静态对象,只能是堆对象(因为new/malloc出来唯一的对象可以用地址访问)
class SingleClass { public: private: SingleClass() {cout<<"Have done create!"<<endl;} };
|
2.在类中定义一个静态指针指向该类
class SingleClass { public: private: SingleClass() {cout<<"Have done create!"<<endl;} static SingleClass* _pInstance; };
SingleClass* Singleclass::_pInstace = nullptr;
|
3.定义一个返回值为静态指针的静态函数
非静态函数必须有对象才能调用,static进行修饰后可以直接调用,就能得到唯一对象的地址
class SingleClass { public: static SingleClass* getInstance() { if(_pInstance = nullptr) _pInstance = new SingleClass; return _pInstance; } private: SingleClass() {cout<<"Have done create!"<<endl;} static SingleClass* _pInstance; };
SingleClass* Singleclass::_pInstace = nullptr;
|
单例对象的销毁
在类内部定义一个函数实现对唯一对象的delete
class SingleClass { public: static SingleClass* getInstance() { if(_pInstance = nullptr) _pInstance = new SingleClass; return _pInstance; } static void release() { if(_pInstance) delete _pInstance; } private: SingleClass() {cout<<"Have done create!"<<endl;} static SingleClass* _pInstance; };
|
完整代码
#include <iostream>
using std::cout; using std::endl;
class SingleClass { public: static SingleClass* getInstance() {
if (_pInstance == nullptr) _pInstance = new SingleClass; return _pInstance; } static void release() { if(_pInstance) delete _pInstance; }
private: SingleClass() { cout << "Have done create!" << endl; }
~SingleClass() { cout << "Have done delete!" << endl; }
static SingleClass* _pInstance; };
SingleClass* SingleClass:: _pInstance = nullptr;
void test() { SingleClass* sc2 = SingleClass::getInstance(); } int main() { cout << "abc" << endl; test();
SingleClass* sc3 = SingleClass::getInstance();
SingleClass::release();
return 0; }
|