1.拷贝构造函数
1.1拷贝构造函数基本形式
就类对象而言,相同类型的类对象是通过拷贝构造函数来在对象初始化期间完成整个复制过程的。
拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它的唯一的一个参数是本类型的一个引用变量,该参数是const类型,不可变的。例如:类T的拷贝构造函数的形式为T(const T& t)。
当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:
一个对象以值传递的方式传入函数体
一个对象以值传递的方式从函数返回
一个对象需要通过另外一个已存在的对象进行初始化。
如果没有自己实现拷贝构造函数,编译器会自动生成一个默认的拷贝构造函数,默认的拷贝构造函数完成对象之间的位拷贝,又称浅拷贝。对于任何含有指针变量的类,默认的(浅)拷贝函数注定出错。
浅拷贝只是简单地将一个对象内存的数据复制给另一个对象。在类中含有指针变量状况下,指针变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。
深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
下面实现了一个拷贝构造函数的例子:
class Cgoods
{
public:
Cgoods()
{
cout<<"Cgoods()"<<endl;
}
Cgoods(char *name,int num,double price)
{
cout<<"Cgoods(char *name,int num,double price)"<<endl;
if(NULL == name)
{
return;
}
_name = new char[strlen(name)+1];
strncpy(_name,name,strlen(name)+1);
this->_num = num;
_price = price;
}
//拷贝构造函数
Cgoods(const Cgoods& good)
{
cout<<"Cgoods(Cgoods& good)"<<endl;
_name = new char[strlen(good._name)+1]; //深拷贝
strncpy(_name,good._name,strlen(good._name)+1);
_num = good._num;
_price = good._price;
}
void show()
{
cout<<"name:"<<_name<<endl;
cout<<"num:"<<_num<<endl;