Effective C++_Item11笔记

来源:互联网 发布:oracle导入数据 编辑:程序博客网 时间:2024/04/30 06:09

1.  在重载赋值运算符的时候要避免自我赋值,虽然这看起来并不好,但是实际中可能隐含一些自我赋值的情况,比如循环中的a[i]=a[j],就隐含着在循环过程中的自我赋值的情况

2.  考虑一种情况在一个类中含有一个指针,重载了一个赋值操作符,在这个赋值操作符中会先释放掉自身的指针内存,然后用形参里的那个类的指针创建一个副本存放在当前类中,如果是自我赋值的情况,那么这样自己的这个指针的内存就被释放掉了,自我赋值过程中就会产生一个空指针,从而引发问题

3.  为了避免自我赋值的情况,应当在一个重载的赋值操作符的开始引入一个证同测试,也就是判断一下是不是自我赋值,直接用内存地址比较是否相同即可,如果是自我赋值的话,那么什么也不做跳过就可以了

4.  重载赋值操作符不仅不具有自我赋值安全性,同时也不具有异常安全性,如果在刚才的那种情况下在赋值操作符里如果new出现了异常,被赋值的那一个会持有一个空指针,可以看一下如下代码

ClassA & operator=(const ClassA & __c){       delete this.pointer;       this.pointer=newpointType(*__c.pointer);       return * this;}//在以上的这种情况下自我赋值就会产生异常//避免这种异常可以ClassA & operator=(const ClassA & __c){       if(this==&__c)return *this; //跳过自我赋值       deletethis.pointer;       this.pointer=newpointType(*__c.pointer);       return * this;}//但是以上的这种方法如果new的过程中产生异常的话,那么指针就会成为空指//针,从而产生问题//采用如下的解决方式即可以处理自我赋值又可以处理new的异常ClassA & operator=(const ClassA & __c){       pointType *tmp=this.pointer; //记住原来的指针       this.pointer=newpointerType(*__c.pointer); //指向一个副本       delete tmp;       return * this;}//还有一种最好的方式是//用构造函数创建一个副本对象,然后同这个副本对象与当前对象进行交换swap//这样又好又安全,或者直接在形参中使用值传递,就不用调用构造函数创建一个//新临时对象了

首发于我的个人网站: 点击打开链接

0 0
原创粉丝点击