Effective C++(11) 自我赋值(a=a)时会发生什么?
自我赋值看似有点愚蠢的行为,其实总会发生的首先:它是合法的,其次,它不一定是安全的,再次,它有时候不是那么明显。
先看一个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;
}
class Widget {
...
void swap(Widget& rhs);
...
}; Widget& Widget::operator=(const Wdiget& rhs)
{
Widget temp(rhs);
swap(temp);
return *this;
}
思想:
拷贝构造函数要声明为“按值传递”按值传递会造成一份副本
确保当对象自我赋值时operator=有良好的行为。
包括:
对象来源目标对象地址
语句顺序
确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。
Effective C++(11) 自我赋值(a=a)时会发生什么?的更多相关文章
- 读书笔记 effective c++ Item 11 在operator=中处理自我赋值
1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: class Widget { ... }; Widget w; ... w = w; // assignment to sel ...
- Effective C++ 条款11,12 在operator= 中处理“自我赋值” || 复制对象时不要忘记每一个成分
1.潜在的自我赋值 a[i] = a[j]; *px = *py; 当两个对象来自同一个继承体系时,他们甚至不需要声明为相同类型就可能造成别名. 现在担心的问题是:假如指向同一个对象, ...
- Effective C++ -----条款11: 在operator=中处理“自我赋值”
确保当对象自我赋值时operator=有良好行为.其中技术包括比较“来源 对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap. 确定任何函数如果操作一个以上的对象,而其中多 ...
- Effective C++ 条款11:在operator=中处理"自我赋值"
"自我赋值"发生在对象被赋值给自己时: class Widget { ... }; Widget w; ... w = w; // 赋值给自己 a[i] = a[j]; // 潜在 ...
- Effective C++_笔记_条款11_在operator=中处理“自我赋值”
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为什么会出现自我赋值呢?不明显的自我赋值,是“别名”带来的结果: ...
- 条款11:在operator=中处理“自我赋值”
什么是自我赋值,就是 v = v 这种类型的语句,也许很多人都会说鄙视这种写法,但是如下的写法会不会出现呢? 比如:a[i] = a[j]; // 不巧的是i可能和j相等 *px = *py ...
- 【11】在operator=中处理“自我赋值”
1.自我赋值,看起来愚蠢,但是却合法.有些自我赋值一眼就可看出来.有些自我赋值是潜在的.比如:a[i] = a[j]; *px = *py; 甚至不同类型的指针,都指向同一个地址,也是自我赋值,这一类 ...
- [Effective C++ --011]在operator=中处理“自我赋值”
一.何谓“自我赋值”? 1.1.场合一 直接赋值 w = w; 1.2.场合二 同一数组 a[i] = a[j]: 1.3.场合三 指针 *px = *py: 1.4. ...
- EC读书笔记系列之6:条款11 在operator=中处理自我赋值
记住: ★确保当对象自我赋值时operator=有良好行为.有三种方法:比较“来源对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap技术 ★确定任何函数若操作一个以上对象, ...
随机推荐
- 【Hibernate步步】--一对一映射双向关联具体解释(两)
很抱歉.有两天没更新博客文章,不要写文章一天真的感觉很是空的啊.制定一个写作习惯,想改也改不掉啊.说点题外话,前两天我收到一封私人信件给朋友,我写邀请函的文章OWS文章.一种技术用于研究图标工具,这位 ...
- Python - 缩写(capwords) 和 创建转换表(maketrans) 详细说明
缩写(capwords) 和 创建转换表(maketrans) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27051 ...
- GPS坐标互转:WGS-84(GPS)、GCJ-02(Google地图)、BD-09(百度地图)[转]
WGS-84:是国际标准,GPS坐标(Google Earth使用.或者GPS模块)GCJ-02:中国坐标偏移标准,Google Map.高德.腾讯使用BD-09:百度坐标偏移标准,Baidu Map ...
- Sql使用视图(简单的视图)适合入门-level
创建以便从库更好的数据呼叫和一个数据库,以(例如,该209东东库转移205图书馆) 例:209图书馆有不同的库名:数据库(AIS20140417092531电影库)供应商表(t_Supplier ). ...
- Notification(一个)——使用演示样本的基础知识
main.xml如下面: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ...
- ios结构体httpPost头结构
ios结构体httpPost头结构 by 吴雪莹 NSString* urlStr = @"; NSURL* url = [NSURL URLWithString:urlStr]; NSMu ...
- .NET平台机器学习
.NET平台机器学习资源汇总,有你想要的么? 接触机器学习1年多了,由于只会用C#堆代码,所以只关注.NET平台的资源,一边积累,一边收集,一边学习,所以在本站第101篇博客到来之际,分享给大家.部分 ...
- Roundabout for jQuery
效果图: Roundabout是一个转换静态HTML元素结构为交互式播放区域的jQuery插件(而且并不仅仅是一个转盘,还有许多的形状) 首先你要下载好Jquery.min.js,和Jquery-Ro ...
- Socket 学习(三).1 tcp 通讯
实现了,局域网客户端 对客户端 的通讯. 实际上这是 一个 客户端 兼 服务端 . 2个阿里云服务器测试 效果图: 本地效果图: using System; using System.Collecti ...
- 走进windows编程的世界-----windows进程
Windows进程 1 Windows进程 进程是一个容器,包括了一个应用程序实例的各种资源.Windows多任务的操作系统,因此能够同一时候运行多个进程. 2 Windows进程的 ...