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

class Widget { ... };
Widget w;
...
w = w;                  // 赋值给自己
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* pb;         // 指针,指向一个从heap分配而得的对象
};
// 一个不安全的operator=实现版本
Widget& Widget::operator=(const Widget& rhs) {delete pb;                      // 停止使用当前的bitmappb = new Bitmap(*rhs.pb);       // 使用rhs's bitmap的副本return *this;                   // 见条款10
}

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

自我安全性

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

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

异常安全性

Widget& Widget::operator=(const Widget& rhs) {Bitmap* pOrig = pb;                     // 记住原先的pbpb = new Bitmap(*rhs.pb);delete pOrig;                           // 删除原先的pbreturn *this;
}

copy and swap

class Widget {
...
void swap(Widget& rhs);
...
};
Widget& Widget::operator=(const Widget& rhs) {Widget temp(rhs);swap(temp);return *this;
}
Widget& Widget::operator=(Widget rhs) { // 注意这里是传值swap(rhs);                  return *this;
}

总结

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

转载于:https://www.cnblogs.com/zhonghuasong/p/7443800.html

Effective C++ 条款11:在operator=中处理自我赋值相关推荐

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

    "自我赋值"发生在对象被赋值给自己时: 1 class Widget {...}; 2 Widget w; 3 ... 4 w = w; //赋值给自己 这看起来有点愚蠢,但它合法 ...

  2. Effective C++ 11 在operator=中处理“自我赋值” 笔记

    "自我赋值"发生在对象被赋值给自己时: 1 class Widget {...}; 2 Widget w; 3 ... 4 w = w; //赋值给自己 这看起来有点愚蠢,但它合法 ...

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

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

  4. EC笔记:第二部分:11:在operator=中处理“自我赋值”

    已经一年半没有写过博客了,最近发现学过的知识还是需要整理一下,为知笔记,要开始收费了以前写在为知笔记上笔记也会慢慢的转到博客里. 话不多说,进入正题. 考虑考虑以下场景: 当某个对象对自身赋值时,会出 ...

  5. effective c++条款11扩展——关于拷贝构造函数和赋值运算符

    effective c++条款11扩展--关于拷贝构造函数和赋值运算符 作者:冯明德 重点:包含动态分配成员的类 应提供拷贝构造函数,并重载"="赋值操作符. 以下讨论中将用到的例 ...

  6. C++尽量在operater=中处理“自我赋值”

    operater=中处理"自我赋值 下面的operator=实现是一份不安全的实现,在自赋值时会出现问题: 1.在开头添加"证同测试" c++ 2.通过确保异常安全来获得 ...

  7. effective C++ 条款 11:在operator= 处理‘自我赋值’

    假设建立一个class来保存一个指针指向一块儿动态分配的位图(bitmap) class Bitmap{...}; class Widget { public: protected: private: ...

  8. effective c++ 条款10 让operator= 返回*this的引用

    如:x = y = z:我们想实现这样的"连锁赋值"在我们的类里应该定义一个operator=的函数并且返回一个*this指针. widget& operator= (co ...

  9. Effective C++ 条款11_不止于此

    在 operator= 中处理 "自我赋值" " 自我赋值 " 发生在对象被赋值给自己时: class Getself { ... }; Getself w; ...

最新文章

  1. linux兼容性,Atom 1.23发布:功能增强,兼容性更好
  2. 内存与mysql_MySQL的内存和相关问题排查
  3. HTTP协议中的Content-Encoding
  4. java 着色问题 回溯算法,C语言使用回溯法解旅行售货员问题与图的m着色问题
  5. aria2c rpc php,aria2c 的基本配置,附带傻瓜式源码
  6. sed 插入多行_Linux三剑客之sed
  7. 前端学习(2552):vue简介
  8. oracle sql 查询优化器,基于ORACLE成本优化器的SQL查询优化分析与应用
  9. javascript拖拽之从浏览器外拖拽(drag)
  10. vs2019社区版+qt5.14.2+Coin3D安装
  11. linux 类似迅雷下载软件,推荐几个可以替代迅雷的下载软件
  12. 三星samsung 3G手机s7220 小技巧
  13. 百度AI之图像识别SDK:车牌识别
  14. 手机android flash,安卓手机flash插件最新版
  15. 流程:论文发表的流程
  16. git push和 git pull的使用
  17. 聚焦分布式资本:中国首家区块链基金如何布局区块链
  18. redolog 、undolog 和binlog
  19. 离散作业用c语言编写覆盖,c语言论文3000字_优秀论文范文3000字_大一论文范文3000字...
  20. Android简易闹钟实现

热门文章

  1. 【边缘检测】RCN:Object Contour and Edge Detection with RefineContourNet
  2. python如何读取文件夹下的子文件夹
  3. 美国人口普查年收入比赛_训练网络对收入进行分类:成人普查收入数据集
  4. 机器学习与不确定性_机器学习求职中的不确定性
  5. Markdown 图标 快捷键
  6. 广东网络借贷中介整改验收,留给平台的时间只有8天!
  7. 乱查征信,贷款不想要了吗?
  8. 《城邦暴力团》:一部奇书、反书、隐书
  9. Matlab与C/C++/Java的一些区别
  10. 一旦有辞职念头就干不长了吗_每天都有辞职不想上班的冲动,你有吗?