1.深拷贝和浅拷贝
在未定义显示拷贝构造函数的情况下,系统会调用默认的拷贝函数——即浅拷贝,它能够完成成员的一一复制。当数据成员中没有指针时,浅拷贝是可行的;但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址,当对象快结束时,会调用两次析构函数,而导致指针悬挂现象,所以,此时,必须采用深拷贝。
深拷贝与浅拷贝的区别就在于深拷贝会在堆内存中另外申请空间来储存数据,从而也就解决了指针悬挂的问题。简而言之,当数据成员中有指针时,必须要用深拷贝。
浅拷贝:
c++的默认构造函数就是浅拷贝,浅拷贝就是简单的赋值操作,如果对象中没有其他的资源(如:堆,文件,系统资源等),则深拷贝和浅拷贝没有什么区别。
class A
{
public:
A(int _data) : data(_data){}
private:
int data;
};
int main()
{
A a(5), b = a; // 仅仅是数据成员之间的赋值
}
深拷贝:
深拷贝是在构造函数时开辟了一个空间用来存储a的值,如果这时进行a = b拷贝操作,只会将a的地址复制b,a和b同时指向该空间,执行析构函数时就会释放同一空间(内存)两次,而导致出错。所有需要自己写一个拷贝函数,并在函数里开辟一个新的空间来放b拷贝后的值。这样就会在执行析构函数时释放各自空间(内存)。
class X
{
public:
X(){};//无参构造
X(int _size) : size(_size)
{
data = new int[size];
} // 为a分配内存
X(const X &_X) : size(_X.size) //拷贝构造
{
data = new int[size];
} // 深拷贝 为拷贝的b分配内存
~X()//析构函数
{
delete [] data;
} // 析构时释放a,b资源
private:
int* data;
int size;
};
int main()
{
X a(5), b = a;
}