用3种方法在 operator= 中处理“自我赋值”
假设你建立一个class 用来保存一个指针指向一块动态分配的位图。
class Bitmap {......};
class Widget{
...
private:
Bitmap* pb ;
};
Widget& Widget::operator= (const Widget& rhs)
{
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}
上面是一份不安全的 operator= 实现版本,因为 operator= 函数内的*this 和 rhs 有可能是同一个对象。欲阻止这种错误有三种方法。
方法一:传统的方法
Widget& Widget::operator= (const Widget& rhs)
{
if( this == rhs ) return *this;
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}
方法二:
Widget& Widget::operator= (const Widget& rhs)
{
Bitmap* pOrig = pb ; pb = new Bitmap(*rhs.pb);
delete pOrig ;
return *this;
}
方法三:所谓的copy and swap 技术
Widget& Widget::operator= (const Widget& rhs)
{
Widget temp( rhs ) ;
swap(temp); return *this;
}
用3种方法在 operator= 中处理“自我赋值”的更多相关文章
- 读书笔记 effective c++ Item 11 在operator=中处理自我赋值
1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: class Widget { ... }; Widget w; ... w = w; // assignment to sel ...
- 【11】在operator=中处理“自我赋值”
1.自我赋值,看起来愚蠢,但是却合法.有些自我赋值一眼就可看出来.有些自我赋值是潜在的.比如:a[i] = a[j]; *px = *py; 甚至不同类型的指针,都指向同一个地址,也是自我赋值,这一类 ...
- Effective C++ 条款11,12 在operator= 中处理“自我赋值” || 复制对象时不要忘记每一个成分
1.潜在的自我赋值 a[i] = a[j]; *px = *py; 当两个对象来自同一个继承体系时,他们甚至不需要声明为相同类型就可能造成别名. 现在担心的问题是:假如指向同一个对象, ...
- 条款11:在operator=中处理“自我赋值”
什么是自我赋值,就是 v = v 这种类型的语句,也许很多人都会说鄙视这种写法,但是如下的写法会不会出现呢? 比如:a[i] = a[j]; // 不巧的是i可能和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技术 ★确定任何函数若操作一个以上对象, ...
- Effective C++_笔记_条款11_在operator=中处理“自我赋值”
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为什么会出现自我赋值呢?不明显的自我赋值,是“别名”带来的结果: ...
- Effective C++ -----条款11: 在operator=中处理“自我赋值”
确保当对象自我赋值时operator=有良好行为.其中技术包括比较“来源 对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap. 确定任何函数如果操作一个以上的对象,而其中多 ...
- NO.10: 在operator=中处理 "自我赋值"
1.确保当对象自我赋值时operator=有良好的行为,其中的技术包括 "来源对象" 和 "目标对象" 的地址,精心周到的语句顺序,以及“ copy and s ...
随机推荐
- 曾经记录——asp.net中的点滴
“<%#....%>”这是数据绑定,里面可以调用C#的方法,比如在数据控件里执行绑定某个字段<%# Eval("Name")%>这样帮顶一个Name的字段. ...
- 转载:Python中的new style class机制实现
1.Python中的对象模型python中所有东西都是对象 class对象:表示Python内置的类型和定义的类型instance对象(实例对象):表示由class对象创建的实例 1.1 对象间的关系 ...
- wall
wall 是在linux中用于发送广播信息的命令,他可以让所有的在线用户都收到信息 wall hi 然后,按Ctrl + c 退出
- poj 3608 Bridge Across Islands
题目:计算两个不相交凸多边形间的最小距离. 分析:计算几何.凸包.旋转卡壳.分别求出凸包,利用旋转卡壳求出对踵点对,枚举距离即可. 注意:1.利用向量法判断旋转,而不是计算角度:避免精度问题和TLE. ...
- Quartz定时任务学习(九)Quartz监听器
Quartz 提供了三种类型的监听器:监听 Job 的,监听 Trigger 的,和监听 Scheduler 自已的. 本章解释如何应用每一种类型来更好的管理你的 Quartz 应用,并获悉到什么事件 ...
- 查看数据库中有哪些活动的事务,对应的会话id,执行的语句
select dbt.database_id, DB_NAME(dbt.database_id) '数据库名', dbt.transaction_id, at.name, at.transaction ...
- OpenStack_Swift源代码分析——创建Ring及加入�设备源代码算法具体分析
1 创建Ring 代码具体分析 在OpenStack_Swift--Ring组织架构中我们具体分析了Ring的具体工作过程,以下就Ring中添加�设备,删除设备,已经又一次平衡的实现过程作具体的介绍. ...
- flex利用webservice上传照片
WebService端代码 /// <summary> /// 上传文件到远程server /// </summary> /// <param name="fi ...
- JSP中嵌入java代码的标签方式(转)
(1)声明变量或方法 : <%! 声明; %> :慎重使用,因为此方法定义的是全局变量 (2)java片段(scriptlet): <% java代码; %> (3)表达式 ...
- 第五篇:web之前端之float的几种清除浮动方式
前端之float的几种清除浮动方式 前端之float的几种清除浮动方式 本节内容 1.float清除方式1 2.float清除方式2 3.float清除方式3 4.float清除方式4 1.flo ...