Effective C++(11) 自我赋值(a=a)时会发生什么?
来源:互联网 发布:python np.split axis 编辑:程序博客网 时间:2024/06/05 08:08
问题聚焦:
先看一个Demo自我赋值看似有点愚蠢的行为,其实总会发生的首先:它是合法的,其次,它不一定是安全的,再次,它有时候不是那么明显。
class Widget { ... };Widget w;... /** 最明显的自我赋值 **/w = w; /** 不那么明显的自我赋值 **/// 在某个地方实现了i = j或者相同作用的事情a[i] = a[j]/** 潜在的自我赋值 **/*px = *py;/** 更为隐蔽的自我赋值“别名” **/class Base { ... };class Derived : public Base { ... };void doSomething( const Base& rb, Derived* pd); // rb 和 *pd可能是同一对象
一般而言,如果某段代码操作指针和引用,而它们被用来指向多个相同类型的对象,就需要考虑这些对象是否为同一个了。
自我赋值可能带来的两种潜在的危险:
- 自我赋值安全性
- 异常安全
来看下面的例子:
class Bitmap { ... };class Widget { ... private: Bitmap* pd;};/** operator=的代码实现 **/Widget&Widget::operator=(const Widget& rhs){ delete pb; pb = new Bitmap(*rhs.pb); return *this;}
自我赋值安全性:
若rhs和当前对象是同一对象,那么在销毁当前对象的pb时,把rhs的对象也销毁了。
改进:认同测试
/** operator=的代码实现 **/Widget&Widget::operator=(const Widget& rhs){ if (this == &rhs) return *this; // 认同测试 delete pb; pb = new Bitmap(*rhs.pb); return *this;}
上述改进后的代码避免了自我赋值安全性问题。
我们来关注一下第二个问题
异常安全性:
改进一:精心安排语句如果new Bitmap()发生异常,那么结果就是pb赋值直白,Widget最终持有一个指针指向一块被删除的Bitmap。
/** operator=的代码实现 **/Widget&Widget::operator=(const Widget& rhs){ Bitmap* pOrig = pb; pb = new Bitmap(*rhs.pb); // 如果new Bitmap抛出异常,pb保持原状 delete pOrig; return *this;}
改进方案二:copy and swap
class Widget {...void swap(Widget& rhs);...};Widget& Widget::operator=(const Wdiget& rhs){ Widget temp(rhs); swap(temp); return *this;}
思想:
拷贝构造函数要声明为“按值传递”按值传递会造成一份副本
小结:
确保当对象自我赋值时operator=有良好的行为。
包括:
对象来源目标对象地址语句顺序确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。
参考资料:
《Effective C++ 3rd》
0 0
- Effective C++(11) 自我赋值(a=a)时会发生什么?
- (++a)+=(a++)到底发生了什么
- 【Effective c++】条款11:在operator=中处理“自我赋值”
- 《Effective C++》学习笔记条款11 在operator =中处理“自我赋值”
- Effective C++——》条款11:在operator=中处理自我赋值
- Effective C++:条款11:在operator= 中处理“自我赋值”。
- 读书笔记《Effective C++》条款11:令operator=中处理”自我赋值“
- C++中在operator=中处理“自我赋值”(11)---《Effective C++》
- $a=58 发生了什么?
- C++ 13.2 类赋值操作符----定义该类型对象赋值时会发生什么(有不懂)
- Effective C++ 条款11 在赋值操作符operator=中处理“自我赋值”
- 在operator=中处理自我赋值(Effective C++_11)
- Effective c++学习笔记——条款11:在operateor=中自我赋值
- Effective c++学习笔记——条款11:在operateor=中自我赋值
- Effective C++ 学记之11 在operator=中处理“自我赋值“
- Effective C++ Item 11 在operator= 中处理“自我赋值”
- Effective C++ 读书笔记 条款11:在operator= 中处理"自我赋值"
- Effective C++ Item 11-在operator = 中处理"自我赋值"
- 创建seam文件
- 【算法导论】幻方算法
- 单例模式
- eclipse的注释字体大小如何修改?
- DREAM Building on Linux for Android(错误记录)
- Effective C++(11) 自我赋值(a=a)时会发生什么?
- activemq使用demo
- 第九章 接口
- JAVA设计模式-工厂模式
- 操作系统的几个问题
- Linux下各个目录详细介绍
- 在相关网站首页加载到手机上浏览网页
- 原型模式
- 杨氏查找矩阵