1、概念
只有一个形参,该形参是对本类类型对象的引用,一般用const来修饰,用已存在的类类型对象创建新对象时由编译器自动调用。
2、特征
class CGoods
{
public:
/*CGoods()
{}*/
CGoods(const CGoods& rhs)
{
cout << this <<":CGoods::CGoods(char* , float , int )" << endl;
_name = new char[strlen(rhs._name) + 1]();
strcpy(_name, rhs._name);
_price = rhs._price;
_amount = rhs._amount;
}
CGoods(char* name, float price, int amount)
{
cout << this << ":CGoods::CGoods(char* , float , int )" << endl;
_name = new char[strlen(name) + 1]();
strcpy(_name, name);
_price = price;
_amount = amount;
}
~CGoods()
{
cout << this << ":~CGoods()" << endl;
delete[] _name;
_name = NULL;
}
private:
char* _name;
float _price;
int _amount;
};
int main()
{
CGoods good1("good1", 500, 10);
CGoods good2 = good1;
return 0;
}
(1)拿一个已经存在的对象生成一个相同类型的新对象。
(2)相当于构造函数的一个重载形式。
(3)拷贝构造函数的参数必须使用引用形参,引用传值方式会引发无穷的递归调用。
- 如果没有引用,编译器会这样进行
- 如果传的是引用,引用就是已存在的对象good1起一个别名rhs ,系统自带解引用,直接用rhs进行操作,不在调用构造函数。
(4)上面的代码,我们使用的是深拷贝进行,如果使用浅拷贝时,相当于两个指针指向了同一个堆内存,而在进行析构函数时会先释放good2 ,而good1生存周期到了之后调用析构就会导致释放一个野指针,程序崩溃。
而深拷贝就是重新开辟一块堆内存,把已存在的good1的东西拷贝过来。这样他们在释放时就不会相互影响。
CGoods(const CGoods& rhs)
{
_name = rhs._name;//浅拷贝
_price = rhs._price;
_amount = rhs._amount;
}