Effective C++ 条款11:在operator=中处理自我赋值
”自我赋值”发生在对象被赋值给自己时:
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;
}
总结
- 确保当对象自我赋值时operator=有良好行为。其中技术包括比较”来源对象”和”目标对象”的地址、精心周到的语句顺序、以及copy-and-swap.
- 确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。
转载于:https://www.cnblogs.com/zhonghuasong/p/7443800.html
Effective C++ 条款11:在operator=中处理自我赋值相关推荐
- 条款11 在operator=中处理“自我赋值”
"自我赋值"发生在对象被赋值给自己时: 1 class Widget {...}; 2 Widget w; 3 ... 4 w = w; //赋值给自己 这看起来有点愚蠢,但它合法 ...
- Effective C++ 11 在operator=中处理“自我赋值” 笔记
"自我赋值"发生在对象被赋值给自己时: 1 class Widget {...}; 2 Widget w; 3 ... 4 w = w; //赋值给自己 这看起来有点愚蠢,但它合法 ...
- 条款11:在operator=中处理“自我赋值”
什么是自我赋值,就是 v = v 这种类型的语句,也许很多人都会说鄙视这种写法,但是如下的写法会不会出现呢? 比如:a[i] = a[j]; // 不巧的是i可能和j相等 *px = *py ...
- EC笔记:第二部分:11:在operator=中处理“自我赋值”
已经一年半没有写过博客了,最近发现学过的知识还是需要整理一下,为知笔记,要开始收费了以前写在为知笔记上笔记也会慢慢的转到博客里. 话不多说,进入正题. 考虑考虑以下场景: 当某个对象对自身赋值时,会出 ...
- effective c++条款11扩展——关于拷贝构造函数和赋值运算符
effective c++条款11扩展--关于拷贝构造函数和赋值运算符 作者:冯明德 重点:包含动态分配成员的类 应提供拷贝构造函数,并重载"="赋值操作符. 以下讨论中将用到的例 ...
- C++尽量在operater=中处理“自我赋值”
operater=中处理"自我赋值 下面的operator=实现是一份不安全的实现,在自赋值时会出现问题: 1.在开头添加"证同测试" c++ 2.通过确保异常安全来获得 ...
- effective C++ 条款 11:在operator= 处理‘自我赋值’
假设建立一个class来保存一个指针指向一块儿动态分配的位图(bitmap) class Bitmap{...}; class Widget { public: protected: private: ...
- effective c++ 条款10 让operator= 返回*this的引用
如:x = y = z:我们想实现这样的"连锁赋值"在我们的类里应该定义一个operator=的函数并且返回一个*this指针. widget& operator= (co ...
- Effective C++ 条款11_不止于此
在 operator= 中处理 "自我赋值" " 自我赋值 " 发生在对象被赋值给自己时: class Getself { ... }; Getself w; ...
最新文章
- linux兼容性,Atom 1.23发布:功能增强,兼容性更好
- 内存与mysql_MySQL的内存和相关问题排查
- HTTP协议中的Content-Encoding
- java 着色问题 回溯算法,C语言使用回溯法解旅行售货员问题与图的m着色问题
- aria2c rpc php,aria2c 的基本配置,附带傻瓜式源码
- sed 插入多行_Linux三剑客之sed
- 前端学习(2552):vue简介
- oracle sql 查询优化器,基于ORACLE成本优化器的SQL查询优化分析与应用
- javascript拖拽之从浏览器外拖拽(drag)
- vs2019社区版+qt5.14.2+Coin3D安装
- linux 类似迅雷下载软件,推荐几个可以替代迅雷的下载软件
- 三星samsung 3G手机s7220 小技巧
- 百度AI之图像识别SDK:车牌识别
- 手机android flash,安卓手机flash插件最新版
- 流程:论文发表的流程
- git push和 git pull的使用
- 聚焦分布式资本:中国首家区块链基金如何布局区块链
- redolog 、undolog 和binlog
- 离散作业用c语言编写覆盖,c语言论文3000字_优秀论文范文3000字_大一论文范文3000字...
- Android简易闹钟实现
热门文章
- 【边缘检测】RCN:Object Contour and Edge Detection with RefineContourNet
- python如何读取文件夹下的子文件夹
- 美国人口普查年收入比赛_训练网络对收入进行分类:成人普查收入数据集
- 机器学习与不确定性_机器学习求职中的不确定性
- Markdown 图标 快捷键
- 广东网络借贷中介整改验收,留给平台的时间只有8天!
- 乱查征信,贷款不想要了吗?
- 《城邦暴力团》:一部奇书、反书、隐书
- Matlab与C/C++/Java的一些区别
- 一旦有辞职念头就干不长了吗_每天都有辞职不想上班的冲动,你有吗?