C++中类的拷贝有两种,浅拷贝和深拷贝。
当出现类的等号赋值则要调用拷贝构造函数
当无指定的拷贝构造函数,则编译器会调用默认的拷贝构造函数。当不涉及到堆内存时用浅拷贝完全可以,否则的话会出现内存的异常情况。
例如:当一个类中有指针时,浅拷贝仅仅拷贝指针的值,这相当于多个类中的该指针都指向同一个地址,析构时会出现错误。
class test
{
int value;
int* p;
public:
void show()
{
cout << value << " " << p << " " << *p << endl;
}
test(int x, int y)
{
value = x;
p = new int(y);
}
~test()
{
if (p != nullptr)
{
delete p;
p = nullptr;
}
}
};
int main()
{
test a(10, 20);
test b = a;
a.show();
b.show();
system("pause");
}
该代码中,编译器会调用默认的拷贝构造函数,a和b中的p指针指向同一个地址,会出现地址二次释放的问题。因为a析构时,p指向的内存被释放了一次,b析构时p指向的内存又被释放了一次。
所以这里就需要深拷贝来解决这个问题,深拷贝指的就是当拷贝对象中有对其他资源的引用时(引用可以是指针或引用)时,另开辟一块新的资源,而不再对拷贝对象中有对其他资源的引用的指针或引用进行单纯的赋值。
在代码中加入自定义的拷贝构造函数,即可解决上述代码的问题。
test(const test& a)
{
value = a.value;
p = new int(*a.p);
}