我们直接通过例子来看深拷贝与浅拷贝的区别
我们定义一个类:
class Array
{
public:
Array();
Array(const Array &arr);
~Array();
private:
int m_iCount;
};
我们实例化两个对象,一个直接实例化,另一个通过拷贝的方式实例化
Array arr1;
Array arr2(arr1);
编写函数:
Array::Array()
{
cout<<"Array()默认构造\n";
}
Array::Array(const Array &arr)
{
m_iCount=arr.m_iCount;
}
Array::~Array()
{
cout<<"~Array()析构\n";
}
实例化arr2时会调用拷贝构造函数
这样,直接将arr中m_iCount赋值给当前对象的m_iCount的方式就叫浅拷贝,简单的变量成员当然可以如此赋值,但是遇到指针时这样赋值会出大问题。
我们再定义一个数据成员m_pArr,是指针型:
class Array
{
public:
Array();
Array(const Array &arr);
~Array;
private:
int m_iCount;
int *m_pArr;
};
然后实例化两个对象arr1和arr2,再用上述方式进行赋值
Array::Array(const Array &arr)
{
m_iCount=arr.m_iCount;
m_pArr=arr.m_pArr;
}
Array::~Array()
{
delete m_pArr;
m_pArr=NULL;
cout<<"~Array()析构\n";
}
这样会出现错误,出错的原因是:
arr1.m_pArr和arr2.m_pArr指向的是同一块内存,而我们在析构函数中进行内存释放,这样就会导致同一块内存被释放两次。
所以要用深拷贝的方式进行赋值,也就是不要单纯的将地址拷贝,而是将地址内存储的内容进行拷贝
Array::Array(int count)
{
cout<<"Array()默认构造\n";
/*为了给m_pArr申请一个内存空间,必须要给m_iCount确切的初值
因此默认构造函数要带个参数,所以需要在类的声明里将默认构造函数改成有参数的*/
m_icount=count;
m_pArr=new int[m_iCount];
//使用for循环给m_pArr赋值
for(int i=0;i<m_iCount;i++)
{
m_pArr[i]=i;
}
}
Array::Array(const Array &arr)
{
m_iCount=arr.m_iCount;
//m_pArr=arr.m_pArr;
//深拷贝的形式
m_pArr=new int[m_iCount];
for(int i=0;i<m_iCount;i++)
{
m_pArr[i]=arr.m_pArr[i];
}
}
Array::~Array()
{
delete m_pArr;
m_pArr=NULL;
cout<<"~Array()析构\n";
}
这样在运行代码就不会出现问题啦!