1.拷贝构造
+ 它是一个特殊的构造函数
+ 参数是唯一的:对对象的引用
+ 作用: 实现通过对象去构造对象
namespace myData { class Girl { public: //Girl() { cout << "默认构造" << endl; } Girl(string name) :name(name) { cout << "有参构造" << endl; } //拷贝构造 Girl(Girl& obj) { this->name = obj.name; cout << "拷贝构造" << endl; } //构造委托:允许一个构造函数调用另一个构造函数去初始化数据 Girl() :Girl("小可爱") { cout << "无参构造" << endl; } void print() { cout << name << endl; } Girl& operator=(Girl &obj) { name = obj.name; return obj; } protected: string name; }; } int main() { myData::Girl a("小可爱"); //有参构造 myData::Girl b(a); //拷贝构造 myData::Girl c = a; //拷贝构造 myData::Girl d; //默认构造(无参构造) d = a; //不调用拷贝构造,是运算符重载实现的 return 0; }
2.浅拷贝与深拷贝
+ 默认的拷贝构造函数是浅拷贝
+ 深拷贝,一定拷贝构造函数做了动态内存申请,以及值的复制
class MM { public: MM(const char* name) { this->name = new char[strlen(name) + 1]; strcpy(this->name, name); } //浅拷贝导致内存的重复释放 MM(MM& obj) { this->name = obj.name; } ~MM() { delete[]name; } protected: char* name; }; int main() { MM mm("小可爱"); MM baby(mm); //baby对象释放导致重复释放 return 0; }
修改:
//深拷贝 MM(MM& obj) { this->name = new char[strlen(obj.name) + 1]; strcpy(this->name, obj.name); }
3.类的组合
+ 以另一个类的对象为数据成员称之为类的组合
+ 构造函数写法必须采用初始化参数列表的写法: 构造函数名(形参1,形参2..):类名(形参1),类名(形参2)...{}
+ 构造和析构顺序问题
class A { public : int a; A(int a) :a(a) { cout << a << endl; } }; class B { public: int b; B(int b) :b(b) { cout << b << endl; } }; class C { public: int c; C(int c) :c(c) { cout << c<< endl; } }; class D { public: //分支类的构造顺序只与对象的声明顺序有关 B bobj; A aobj; C cobj; int d; //构造写法:必须采用初始化参数列表,并且必须调用分支类的构造函数 D(int aa,int bb,int cc,int dd):aobj(aa),bobj(bb),cobj(cc),d(dd){ cout << d << endl; } }; int main() { D d(1, 2, 3, 4); //先调用分之类的构造函数,在执行自己的构造函数 //结果:2 1 3 4 return 0; }
4.this指针
+ this指针是代表每一个抽象对象的地址
+ this指针可以避免形参名字和数据成员名相同
+ 一个对象的成员返回对象本身或者对象的地址