”自我赋值”发生在对象被赋值给自己时:

  1. class Widget { ... };
  2. Widget w;
  3. ...
  4. w = w; // 赋值给自己
  5. a[i] = a[j]; // 潜在的自我赋值
  6. *px = *py; // 潜在的自我赋值
  7. class Base { ... };
  8. class Derived: public Base { ... };
  9. void doSomething(const Base& rb, Derived* pd); // rb和*pd有可能其实是同一对象

尝试自我管理资源

  1. class Bitmap { ... };
  2. class Widget {
  3. ...
  4. private:
  5. Bitmap* pb; // 指针,指向一个从heap分配而得的对象
  6. };
  7. // 一个不安全的operator=实现版本
  8. Widget& Widget::operator=(const Widget& rhs) {
  9. delete pb; // 停止使用当前的bitmap
  10. pb = new Bitmap(*rhs.pb); // 使用rhs's bitmap的副本
  11. return *this; // 见条款10
  12. }

可能出现的问题就是,*this和rhs可能是同一个对象,最后会导致自己持有一个指针指向一个已被删除的对象!

自我安全性

  1. Widget& Widget::operator=(const Widget& rhs) {
  2. if (this == rhs) return *this; // 证同测试
  3. // 如果是自我赋值,就不做任何事情
  4. delete pb;
  5. pb = new Bitmap(*rhs.pb);
  6. return *this;
  7. }

以上代码确实解决了自我赋值的问题,但是会引发异常的问题,如果new Bitmap导致异常了,那么Widget最终会持有一个指针指向一块被删除的Bitmap。

异常安全性

  1. Widget& Widget::operator=(const Widget& rhs) {
  2. Bitmap* pOrig = pb; // 记住原先的pb
  3. pb = new Bitmap(*rhs.pb);
  4. delete pOrig; // 删除原先的pb
  5. return *this;
  6. }

copy and swap

  1. class Widget {
  2. ...
  3. void swap(Widget& rhs);
  4. ...
  5. };
  6. Widget& Widget::operator=(const Widget& rhs) {
  7. Widget temp(rhs);
  8. swap(temp);
  9. return *this;
  10. }
  11. Widget& Widget::operator=(Widget rhs) { // 注意这里是传值
  12. swap(rhs);
  13. return *this;
  14. }

总结

  1. 确保当对象自我赋值时operator=有良好行为。其中技术包括比较”来源对象”和”目标对象”的地址、精心周到的语句顺序、以及copy-and-swap.
  2. 确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。

Effective C++ 条款11:在operator=中处理"自我赋值"的更多相关文章

  1. Effective C++ -----条款11: 在operator=中处理“自我赋值”

    确保当对象自我赋值时operator=有良好行为.其中技术包括比较“来源 对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap. 确定任何函数如果操作一个以上的对象,而其中多 ...

  2. 读书笔记 effective c++ Item 11 在operator=中处理自我赋值

    1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: class Widget { ... }; Widget w; ... w = w; // assignment to sel ...

  3. EC读书笔记系列之6:条款11 在operator=中处理自我赋值

    记住: ★确保当对象自我赋值时operator=有良好行为.有三种方法:比较“来源对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap技术 ★确定任何函数若操作一个以上对象, ...

  4. Effective C++_笔记_条款11_在operator=中处理“自我赋值”

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为什么会出现自我赋值呢?不明显的自我赋值,是“别名”带来的结果: ...

  5. 11——在operator=中处理自我赋值

    在operator=函数中加一个测试: if(&rhs==this) copy and swap

  6. Effective C++ 条款11,12 在operator= 中处理“自我赋值” || 复制对象时不要忘记每一个成分

    1.潜在的自我赋值     a[i] = a[j];     *px = *py; 当两个对象来自同一个继承体系时,他们甚至不需要声明为相同类型就可能造成别名. 现在担心的问题是:假如指向同一个对象, ...

  7. 条款11:在operator=中处理“自我赋值”

    什么是自我赋值,就是 v = v 这种类型的语句,也许很多人都会说鄙视这种写法,但是如下的写法会不会出现呢? 比如:a[i] = a[j];      // 不巧的是i可能和j相等 *px = *py ...

  8. 【11】在operator=中处理“自我赋值”

    1.自我赋值,看起来愚蠢,但是却合法.有些自我赋值一眼就可看出来.有些自我赋值是潜在的.比如:a[i] = a[j]; *px = *py; 甚至不同类型的指针,都指向同一个地址,也是自我赋值,这一类 ...

  9. [Effective C++ --011]在operator=中处理“自我赋值”

    一.何谓“自我赋值”? 1.1.场合一 直接赋值 w = w; 1.2.场合二 同一数组         a[i] = a[j]: 1.3.场合三 指针         *px = *py: 1.4. ...

随机推荐

  1. 数据库读写分离(aop方式完整实现)

    http://blog.csdn.net/machunlin2010/article/details/46471983

  2. 关于vs2013中包含目录,以及库目录配置相对路径的问题

    记住一句话即可! 相对路径: 是相对于你的工程的*.vcxproj的路径!!!

  3. 第一个Gradle入门程序

    参考:http://www.importnew.com/15881.html 准备工作 1.gradle编译环境 下载gradle编译包(http://www.gradle.org/downloads ...

  4. 巨蟒python全栈开发数据库攻略2:基础攻略2

    1.存储引擎表类型 2.整数类型和sql_mode 3.浮点类&字符串类型&日期类型&集合类型&枚举类型 4.数值类型补充 5.完整性约束

  5. ios 画图总结

    0 CGContextRef context = UIGraphicsGetCurrentContext(); 设置上下文1 CGContextMoveToPoint 开始画线2 CGContextA ...

  6. git --fast-version-control

    --distributed-is-the-new-centralized 读二进制文件 python  读doc  xls 几乎所有的版本控制系统都以某种形式支持分支.使用分支意味着你可以把你的工作从 ...

  7. Spring MVC 根据请求方法限定:请求方法(四)

    请求方法 说明 GET 使用GET方法检索一个表述(representation)——也就是对资源的描述.多次执行同一GET请求,不会对系统造成影响,GET方法具有幂等性[指多个相同请求返回相同的结果 ...

  8. Shell正则表达式和文本处理工具

    作业一:整理正则表达式博客 一.什么是正则 正则就是用一些具有特殊含义的符号组合而成(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. 通配符是由shell解释得. ...

  9. HTML里引号的输出与显示

    关于输入框中显示双引号和单引号 前台显示解决办法: 方法一: 单引号<input type="text" value="'"> 双引号<inp ...

  10. 我的Android进阶之旅------>Java字符串格式化方法String.format()格式化float型时小数点变成逗号问题

    今天接到一个波兰的客户说有个APP在英文状态下一切运行正常,但是当系统语言切换到波兰语言的时候,程序奔溃了.好吧,又是我来维护. 好吧,先把系统语言切换到波兰语,切换到波兰语的方法查看文章 我的And ...