1、拷贝构造
当一个已构造了的对象要构造新的对象时,拷贝构造函数被调用。也就是对象需要拷贝时,拷贝构造函数就被调用。如一下几个情况:
1)对象以值传递方式传入函数体。
2)对象以值传递方式从函数体返回。
3)新对象要通过一个已构造完成的对象进行构造。
在C++里面都有一个默认的拷贝构造函数。默认的拷贝构造函数是浅拷贝,一般无法满足实际的需求。
2、浅拷贝和深拷贝
浅拷贝:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源没有重新分配则为浅拷贝。
深拷贝:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源没有重新分配则为浅拷贝。像指针类型的成员变量,此时应该使用深拷贝;例如A和B含有指针变量,A=B发生了浅拷贝,两者的指针指向了同一块区域。若A调用析构函数,而B变量还在使用;此时这块内存已经被释放了,若B再去使用则会出现野指针错误。因此拷贝时,新对象应该再次向系统申请一块内存空间,故而需要深拷贝。
下面是深拷贝的一个例子:
#include <iostream>
using namespace std;
class A
{
public:
A() //默认无参数构造函数
{
cout << "I am Construction1." << endl;
data = new int;
*data = 0;
}
A(int *_data) //带参数的构造函数
{
cout << "I am Constructor1." << endl;
data = new int;
*data = *_data;
}
A(const A& a) //拷贝构造函数
{
cout << "I am Copy Constructor2." << endl;
data = new int;
*data = *(a.data);
}
A& operator = (const A &a) //运算符重载
{
cout << "I am Operator = !" << endl;
cout << "C~~~~~" << endl;
if(&a == this){cout << "SameObj!" << endl; return *this; }
data = new int;
*data = *(a.data);
return *this;
}
~A() //析构函数
{
cout << "I am Destructor" << endl;
if(data != NULL)
{
delete data;
}
}
void print()
{
cout << "\tdata: " << *data << endl;
}
private:
int *data; //指针变量。
};
int main()
{
A z; //调用默认构造函数
z.print();
int x = 100;
A a(&x); //调用带参数的构造函数
a.print();
A b = a; //调用了拷贝构造函数(属于深拷贝)
b.print();
z = b; //调用=重载运算符
z.print();
return 0;
}