c++深拷贝和浅拷贝
两个的区别
- 在未定义显示拷贝构造函数的情况下,系统会调用默认的拷贝函数——即浅拷贝,它能够完成成员的一一复制。当数据成员中没有
指针 时,浅拷贝是可行的,但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址 ,当对象快结束时,会调用两次析构函数,从而导致指针悬挂现象,所以,此时,必须采用深拷贝。
class Widget{
public:
Widget();
Widget(const Widget&rhs);
Widget& operator=(const Widget &rhs);
};
Widget w1;
Widget w2(w1);
w1=w2;
Widget w3=w2;
- 深拷贝和浅拷贝的区别就在于深拷贝会在堆内存中另外申请空间来存储数据,从而也就解决了指针悬挂的问题。
当数据成员中有指针时,必须要用浅拷贝。
解释
- c++默认的拷贝构造函数时浅拷贝
- 浅拷贝就是对象数据成员之间的简单复制,如你设计了一个类而没有通过它的复制构造函数,当用该类的一个对象去给另一个对象赋值时所执行的过程就是浅拷贝,如:
class A
{
public:
A(int _data):data(_data){}
A();
private:
int data;
}
int main()
{
A a(5);
A b=a;
}
深拷贝
class A
{
public:
A(int _size):size(_size)
{
data = new int[size];
}
A();
~A()
{
delete []data;
}
private:
int *data;
int size;
}
int main()
{
A a(5),b=a;
}
- 注:这里的b=a会造成未定义行为,因为类A中的copy构造函数是编译器生成的,所以b = a执行的是一个浅拷贝的过程。
这里b的指针和a的指针指向了堆上的同一块内存,a和b析构时,b先把data执行的分配的内存释放了一次,而后a析构时又将这块已经被释放的内存再释放一次,对同一块内存执行2次以上释放的结果是未定义的,所以这会导致内存泄漏或程序崩溃。
深拷贝就是指当拷贝的对象中有对其他资源(如堆、文件、系统等)的引用时,对象另外开辟一块新的资源,而不再对拷贝对象中有对其他资源的引用的指针或引用进行单纯的赋值。
class A
{
public:
A(int _size):size(_size)
{
data = new int[size];
}
A();
A(const A &_A):size(_A.size)
{
data = new int[size];
}
~A()
{
delete []data;
}
private:
int *data;
int size;
}
int main()
{
A a(5),b=a;
}
|