浅拷贝:简单的赋值拷贝 *** 作(这个是系统默认提供的)
深拷贝:在堆区重新释放空间,进行拷贝 *** 作(要自己写的)
简单来说,只要类属性里有指针等就必须利用深拷贝 *** 作
为便于深刻理解,先看一个实例:
#include
using namespace std;
class Person ******Person类分隔符*******
{
public:
Person(){
cout<<"默认构造函数的调用\n";
}
Person(int age)
{
cout<<"有参构造函数的调用\n";
m_age=age;
}
~Person()
{
cout<<"析构函数的调用\n";
}
int m_age;
}; ******Person类分隔符*******
int main()
{
Person a(10);
Person b(a);
cout<<"a的年龄为:"<
运行结果:
运行结果显然没有问题,我们在初始化类b的时候,系统调用了默认拷贝构造函数,把a中的值传递给了b;下面,我们增加类Person的一个指针属性m_height,并且把身高属性放置到堆区:
tip:堆区由程序员手动开创与释放,new出来的数据就位于堆区
#include
using namespace std;
class Person ******Person类分隔符*******
{
public:
Person(){
cout<<"默认构造函数的调用\n";
}
Person(int age,int height)
{
cout<<"有参构造函数的调用\n";
m_age=age;
m_height=new int(height); //**
}
~Person()
{
cout<<"析构函数的调用\n";
}
int m_age;
int* m_height;
}; ******Person类分隔符*******
int main()
{
Person a(19,170);
Person b(a);
cout<<"a的年龄为:"<
运行结果为:
运行结果看起来没问题,但是代码实际上是不规范的;堆区的数据需要程序员手动开创与释放,需要用到析构函数,我们进行析构代码的完善:
~Person()
{
//析构代码,将堆区开辟的数据释放干净
if(m_height!=NULL)
{
delete m_height;
m_height=NULL; //防止指针滞空变成野指针
}
cout<<"析构函数的调用\n";
}
但当继续运行程序的时候会发现代码已经崩了(部分编译器现象不明显,如Dev,这里不再截图),什么原因导致的?我们分析一下:
二次释放同一块内存会被编译器视为非法 *** 作;可知,浅拷贝带来的问题就是堆区的内存被重复释放。解决这个问题就需要利用深拷贝,具体做法便是重新开辟一个内存空间存放数据,利用深拷贝构造函数使b的指针指向新开辟的空间,这样,a与b各指向一块堆区的数据,两块空间存放的数据是一样的,这样就在拷贝的同时避免了对同一空间的重复释放问题。
具体代码实现如下:
#include
using namespace std;
class Person *****类Person*****
{
public:
Person(){
cout<<"默认构造函数的调用\n";
}
Person(int age,int height)
{
cout<<"有参构造函数的调用\n";
m_age=age;
m_height=new int(height);
}
Person(const Person& p)
{
cout<<"拷贝构造函数的调用"<
运行结果为:
———— ———— ———— —————分割线———— ———— ———— ———— ————
下面附两张截图:
浅拷贝时两个对象height属性的地址:
深拷贝时两个对象height的地址:
如果对你有用,希望优秀的你能给作者一个小小的赞和收藏[emoji]
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)