1. 浅拷贝
一般调用默认的拷贝函数
类名(const 类名&对象名){将对象的内容实现复制}
源代码理解
#include<iostream>
using namespace std;
class Test
{
private:
int* p;
public:
Test(int x)
{
this->p = new int(x);
cout << "对象被创建" << endl;
}
~Test()
{
if (p != NULL)
{
delete p;
}
cout << "对象被释放" << endl;
}
int getX() { return *p; }
};
int main()
{
Test a(10);
//会调用默认的拷贝构造函数
Test b = a;
return 0;
}
运行结果分析
虽然最后可以编译输出结果,但是会弹出错误,如下图所示
错误产生的原因: 在Test b = a;结束后,会调用析构函数进行空间的释放,但是实现的浅拷贝,只是将a的地址复制给了b,此时两个对象指向同一个空间,当第一次调用析构函数的时候将该空间释放,第二次调用析构函数的时候释放的也是该空间,但此时这个空间中已经没有内容了,此时就会产生内存溢出,接下来就引入深拷贝解决这个问题
2. 深拷贝
- 经过了上面的分析可以知道深拷贝的作用就是用来解决内存溢出的问题的,而要解决这个问题的本质就是分配内存.在进行复制的时候就为对象分配一个新的空间,在调用析构函数的时候就不会出现释放空内存的情况了.
解决方法
//浅拷贝时的拷贝构造函数
Test(const Test&test)
{
this->p = test.p;
}
//深拷贝时的拷贝构造函数
Test(const Test&test)
{
this->p = new int(*test.p);
}
完整实现代码
#include<iostream>
using namespace std;
class Test
{
private:
int* p;
public:
Test(int x)
{
this->p = new int(x);
cout << "对象被创建" << endl;
}
Test(const Test& test) {
this->p = new int(*test.p);
}
~Test()
{
if (p != NULL)
{
delete p;
}
cout << "对象被释放" << endl;
}
int getX() { return *p; }
};
int main()
{
Test a(10);
Test b = a;
return 0;
}
运行结果
3. 两者的区别和联系
- 两者都是实现复制
- 在不涉及指针的拷贝时两者没有差别
- 深拷贝重新分配了空间,改变被拷贝对象时拷贝对象不会改变