1:定义
构造函数:用于初始化成员变量,构造类变量。
析构函数:用于释放类成员占用的内存资源。
拷贝构造函数:构造函数的一种,用于从一个已有的对象拷贝为另外一个对象(复制)。
赋值运算符(=):用于两个对象(成员变量)之间的赋值(值的复制)。
2:例程:
如下:
此对象并没有显式的拷贝构造函数和赋值运算符,编译器会为类构造一个隐式的拷贝构造函数和赋值运算符。隐式的拷贝构造函数和赋值运算符进行类全部成员的直接复制操作。
但是有时不得不定义显式的拷贝构造函数和赋值运算符。
三原则:任何时候,只要你提供了析构函数、拷贝构造函数或赋值运算符中的一个,你通常需要三个都提供。
就如上例所示,运行以下代码时:
当运行Person p2(p1);时,执行默认的拷贝构造函数,编译器将p1对象的_id赋给p2对象的_id(OK),将p1对象的_name赋给p2对象的_name(OK);p1对象的指针_house赋给p2对象的指针_house,于是错误出现了,他们同时指向了一块相同的堆内存。
当临时块语句执行完,对象p2析构,它释放自己的_house内存,于是p1内存指向了一块已经释放的内存,这是不允许的。同样赋值运算符也是如此。所以需要显示的拷贝构造函数和赋值运算符。
3:显示构造拷贝构造函数和赋值运算符
显式的拷贝构造函数:
显式的赋值运算符:
Person& operator=(const Person&another){
if(this!=&another){
_id=another._id;
4:其他:
Person pp1;
Person pp2 = pp1;//注意:这是调用拷贝构造函数而非调用赋值运算符。
Person pp3;
Person pp4;
pp4 = pp3; //这里则是调用的赋值运算符。
总结:两个对象构造完了(都已经调用了构造函数),再用=,则是赋值运算。
反之,没有先构造而直接用=,则是拷贝构造。(Person pp2 = pp1;)