详细解析:为什么要写自定义拷贝构造函数和赋值运算符

本文详细介绍了C++类中如何实现深拷贝及赋值运算符,避免了浅拷贝导致的资源重复释放问题,通过实例展示了深拷贝的正确实现方式,并解释了其原理及注意事项。

 

//**********************

//**    ch18_7.cpp    **

//**********************

 

#include <string.h>

#include <iostream.h>

 

class Name{

public:

  Name(){ pName = 0; }

  Name(char* pn){ copyName(pn); }

  Name(Name & s){ copyName(s.pName); }

  ~Name(){ deleteName(); }

  Name & operator =(Name & s)          //赋值运算符

  {

    deleteName();

    copyName(s.pName);

    return *this;

  }

  void display(){ cout << pName << endl; }

protected:

  void copyName(char* pN);

  void deleteName();

  char* pName;

};

 

void Name::copyName(char* pN)

{

  pName = new char[strlen(pN) + 1];

  if(pName)

    strcpy(pName, pN);

}

 

void Name::deleteName()

{

  if(pName){

    delete pName;

    pName = 0;

  }

}

 

void main()

{

  Name s("claudette");

  Name t("temporary");

  t.display();

  t = s;               //赋值

  t.display();

}

在构造函数中该存储区是从堆中分配来的,存在浅拷贝问题,必须自定义赋值运算符和拷贝构造函数。

       赋值运算符以operator=()的名称出现,看起来像一个析构函数后面跟着拷贝构造函数。

就是这个代码:

Name & operator =(Name & s)          //赋值运算符

  {

    deleteName();

    copyName(s.pName);

    return *this;

  }

void copyName(char* pN)

{

  pName = new char[strlen(pN) + 1];

  if(pName)

    strcpy(pName, pN);

}

 

通常赋值运算符有两部分,第一部分与析构函数类似,在其中取消对象已经占用的资源。第二部分与拷贝函数类似,在其中分配新的资源。(就是上面的代码。)

其实上面就是深拷贝的情况了。堆分配的资源最后得delete释放。而那样会引起二义性,会第二次释放已经释放的资源,已经释放的资源的指针早就已经成为野指针了,再对那块未知的位置释放空间会造成错误甚至程序崩溃。

如图就是:

 

 

 

 

Delete无论谁先释放其空间 对方都会释放一个无法找到的空间可能。因为原来的那个空间的地址早就不存在了。

 

那么上面代码怎么解决的呢?

解决办法就是在赋值的时候处理下。过程如下:

创建两个对象,A,B。然后为A存放写资源,在把A赋值给B的时候由赋值运算符函数来处理了。

看图:

本来是:

Name A("claudette");

Name B("temporary");

  

 

然后:

 

 

 

上面图的演示正是代码的实现的效果。A的资源和B的资源各自一份。Delete释放的时候也不会造成因无法释放未知空间而崩溃了。

上面的讨论到此为止。

 

PS

那么有人可能再想,那么麻烦上面操作,我狠一点,既然释放会出问题那么我不用delete释放堆空间不就行了。他是根据这句话来的:“堆对象的作用域是整个程序生命期,所以除非程序运行完毕,否则堆对象作用域不会到期。”

确实这样的确可以防止那种情况,但是代价是内存的占用比较大了,一旦程序大了一直开辟不释放可能会内存溢出。故使用上面自定义复制运算符和自定义拷贝构造函数是很有用的。

 

 参考文献:《C++程序设计教程--钱能》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

helihui123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值