首页 > 分享 > Effective C++——operator =

Effective C++——operator =

**

让operator = 返回一个reference to *this

**

#include <iostream> using namespace std; class Widget { public: Widget(){} ~Widget(){} Widget& operator=(const Widget& obj) { //TODO:赋值操作 return *this; } }; int main() { Widget w1,w2,w3; w1 = w2 = w3; cin.get(); return 0; }

12345678910111213141516171819202122

说明:Widget& operator=(const Widget& obj)函数返回值需要是类的一个引用,目的是为了支持链式编程,否则不支持连等赋值操作。

**

在operator = 中处理自我赋值

**
考虑以下自我赋值的情况
1.Widget w;
w= w;
2. a[i] = a[j];
3. *px = *py;
4. 基类和子类之间的赋值

#include <iostream> using namespace std; class Bitmap { }; class Widget { public: Widget(){} ~Widget(){} //1.缺少异常安全性 //2.缺少自我赋值安全性 Widget& operator=(const Widget& obj) { delete pBitmap_; this->pBitmap_ = new Bitmap(*obj.pBitmap_); return *this; } private: Bitmap *pBitmap_; }; int main() { Widget w1; w1 = w1; cin.get(); return 0; }

123456789101112131415161718192021222324252627282930313233

说明:在w1 = w1 ;语句之后会发生什么?

Widget& operator=(const Widget& obj)函数内部的*this 与obj在自我赋值时是同一个对象,这样的话,delete pBitmap_执行之后会清理obj对象,this->pBitmap_ = new Bitmap(*obj.pBitmap_);这句之后获得的内容将是垃圾内容,因为被清理了。1

解决方案:传统做法是进行一个identity test

//仍缺少异常安全性 Widget& operator=(const Widget& obj) { if(this == &obj) { return *this; } delete pBitmap_; this->pBitmap_ = new Bitmap(*obj.pBitmap_); return *this; }1234567891011

说明:this->pBitmap_ = new Bitmap(*obj.pBitmap_); 内存分配失败或Bitmap拷贝构造函数抛出异常,都将导致pBitmap_ 指向一片垃圾空间12

如何解决这两个问题?
庆幸的是在解决了异常安全性的同时可以避免自我赋值安全性

Widget& operator=(const Widget& obj) { Bitmap* temp = pBitmap_; this->pBitmap_ = new Bitmap(*obj.pBitmap_); delete temp ; return *this; }1234567

思路:异常安全性主要是因为先delete 后又拷贝指针指向的内存空间内容了,当自我赋值时就发生了错误。 现在改为后delete,但这样就容易把刚分配的内存空间给清理了,如此自然想到需要一个临时变量存储之前的指针信息。 1.Bitmap* temp = pBitmap_; 保存旧的需要清理的内存空间指针信息; 2.this->pBitmap_ = new Bitmap(*obj.pBitmap_);获得新的内存空间;此时即使是自我赋值也不会影响,因为没有delete 3.最后清理内存空间 delete temp ; 注:此时如果是自我赋值,即使没有identity test也不会出错。因为第二步指针指向的内存空间内容还是正常数据,唯一区别是指针本身数值不一样了而已。 当然,这里也可以再加上identity test验证,由于自我赋值的概率并不高,验证代码被执行可能性不大,但验证代码本身会带来测试成本,同时执行效率降低。1234567

还有另外一种方法来满足异常安全与自我赋值条件,即copy-and-swap技术,与异常安全密切相关,不在这里继续讨论了。

相关知识

C++赋值运算符重载函数(operator=)
C/C++ 学习手札(四)
a=b++,c++和a=(b++,c++)的区别
C++中+= 是什么意思
JS
6 .9图
C++程序设计(上)练习
C++第二天
C++动物运动会源代码资源
宠物驱虫药在重庆的用户消费分层数据

网址: Effective C++——operator = https://m.mcbbbk.com/newsview578585.html

所属分类:萌宠日常
上一篇: 看小宝宝和宠物狗相处的暖心瞬间,
下一篇: 修车师傅=软件项目管理者