Effective C++ 条款11,12 在operator= 中处理“自我赋值” || 复制对象时不要忘记每一个成分
1、潜在的自我赋值
a[i] = a[j];
*px = *py;
当两个对象来自同一个继承体系时,他们甚至不需要声明为相同类型就可能造成别名。
现在担心的问题是:假如指向同一个对象,当其中一个对象被删,另一个也被删,这会造成不想要的结果。
该怎么办?
比如:
widget& widget:: operator+ (const widget& rhs)
{
delete pd;
pd = new bitmap(*rhs.pb);
return *this; //这里假如*this与rhs是同一个对象。则不好处理。
}
解决方案:
1、证同测试
判断是不是同一个对象,如果是同一个对象,则是自我赋值,不用做任何事。
if(this = &rhs) return *this;
2、记住原先的pb,就是在开辟一个空间存放其原来的地址。我们只需记住在复制pb所指东西前别删除pb;
Bitmap * pOrig = pb; //记住原先的pb
pb = new Bitmap(*rhs.pb); //令pb指向*pb的一个副本
delete pOrig; //删除原先的pb
return *this;
3、直接制作一个副本(引用传递)
widget temp(rhs); //为rhs数据制作一个副本
swap(temp);
4、值传递
swap(rhs);
记住:
1、确保党对象自我赋值时,有良好的行为。其中的技术包括以上四种。
2、确保如果任何函数操作一个以上的对象,而其中多个对象是同一个对象时,其行为一定正确。
还记得条款5中提到编译器在必要时会为我们提供拷贝构造函数和拷贝赋值函数,它们也许工作的不错,但有时候我们需要自己编写自己的拷贝构造函数和拷贝赋值函数。如果这样,我们应确保对“每一个”成员进行拷贝(复制)。
如果你在类中添加一个成员变量,你必须同时修改相应的copying函数(所有的构造函数,拷贝构造函数以及拷贝赋值操作符)。
在派生类的构造函数,拷贝构造函数和拷贝赋值操作符中应当显示调用基类相对应的函数,否则编译器可能又“自作聪明了”。
当你编写一个copying函数,请确保:
(1)复制所有local成员变量;
(2)调用所有基类内的适当copying函数。
但是,我们不该令拷贝赋值操作符调用拷贝构造函数,也不该令拷贝构造函数调用拷贝赋值操作符。想想,一个是拷贝(建立对象),一个是赋值(对象已经存在)。
请记住:
- 1、Copying函数应该确保复制“对象内的所有成员变量”及“所有基类成员”;
- 2、不要尝试以某个copying函数实现另一个copying函数。应该将共同机能放进第三个函数中,并由两个copying函数共同调用。
Effective C++ 条款11,12 在operator= 中处理“自我赋值” || 复制对象时不要忘记每一个成分的更多相关文章
- Effective C++ 条款11:在operator=中处理"自我赋值"
"自我赋值"发生在对象被赋值给自己时: class Widget { ... }; Widget w; ... w = w; // 赋值给自己 a[i] = a[j]; // 潜在 ...
- 条款11:在operator=中处理“自我赋值”
什么是自我赋值,就是 v = v 这种类型的语句,也许很多人都会说鄙视这种写法,但是如下的写法会不会出现呢? 比如:a[i] = a[j]; // 不巧的是i可能和j相等 *px = *py ...
- EC笔记:第二部分:11:在operator=中处理“自我赋值”
已经一年半没有写过博客了,最近发现学过的知识还是需要整理一下,为知笔记,要开始收费了以前写在为知笔记上笔记也会慢慢的转到博客里. 话不多说,进入正题. 考虑考虑以下场景: 当某个对象对自身赋值时,会出 ...
- 【11】在operator=中处理“自我赋值”
1.自我赋值,看起来愚蠢,但是却合法.有些自我赋值一眼就可看出来.有些自我赋值是潜在的.比如:a[i] = a[j]; *px = *py; 甚至不同类型的指针,都指向同一个地址,也是自我赋值,这一类 ...
- Effective C++_笔记_条款11_在operator=中处理“自我赋值”
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为什么会出现自我赋值呢?不明显的自我赋值,是“别名”带来的结果: ...
- Effective C++ -----条款11: 在operator=中处理“自我赋值”
确保当对象自我赋值时operator=有良好行为.其中技术包括比较“来源 对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap. 确定任何函数如果操作一个以上的对象,而其中多 ...
- 读书笔记 effective c++ Item 11 在operator=中处理自我赋值
1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: class Widget { ... }; Widget w; ... w = w; // assignment to sel ...
- EC读书笔记系列之6:条款11 在operator=中处理自我赋值
记住: ★确保当对象自我赋值时operator=有良好行为.有三种方法:比较“来源对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap技术 ★确定任何函数若操作一个以上对象, ...
- [Effective C++ --011]在operator=中处理“自我赋值”
一.何谓“自我赋值”? 1.1.场合一 直接赋值 w = w; 1.2.场合二 同一数组 a[i] = a[j]: 1.3.场合三 指针 *px = *py: 1.4. ...
随机推荐
- MySQL外键设置 级联删除
. cascade方式在父表上update/delete记录时,同步update/delete掉子表的匹配记录 . set null方式在父表上update/delete记录时,将子表上匹配记录的列设 ...
- 关于Powershell执行时的问题
问题1: [问题描述] 使用Invoke-Command命令登录远程主机执行命令时,提示如下错误: [192.168.1.135] 连接到远程服务器失败,错误消息如下: WinRM 客户端无法处理该请 ...
- grunt与seajs结合应用
9.seajs构建的问题 01.png和02.jpg 10.seajs与grunt如何结合开发.两个插件:grunt-cmd-transport grunt-cmd-contact ,去grunt官网 ...
- 在 Yii2 项目中使用 Composer 添加 FontAwesome 字体资源
2014-06-21 19:05 原文 简体 繁體 2,123 次围观 前天帮同事改个十年前的网站 bug,页面上一堆 include require 不禁让人抱头痛哭.看到 V2EX 上的讨论说,写 ...
- ffmpeg常见名词解析
scan_all_pmts, 扫描全部的ts流的"Program Map Table"表.
- 干货 | Elasticsearch Nested类型深入详解
在Elasticsearch实战场景中,我们或多或少会遇到嵌套文档的组合形式,反映在ES中称为父子文档. 父子文档的实现,至少包含以下两种方式: 1)父子文档 父子文档在5.X版本中通过parent- ...
- SPOJ CIRU The area of the union of circles ——Simpson积分
[题目分析] 圆的面积并. 直接Simpson积分,(但是有计算几何的解法,留着flag). simpson积分,如果圆出现了不连续的情况,是很容易出事情的.(脑补一下) 但是没有什么办法,本来就是一 ...
- N*N数码问题
奇数码问题 时间限制: 1 Sec 内存限制: 128 MB 题目描述 你一定玩过八数码游戏,它实际上是在一个3*3的网格中进行的,1个空格和1~8这8个数字恰好不重不漏地分布在这3*3的网格中. ...
- 洛谷 [P2734] 游戏
博弈论+区间dp 有博弈论吗?大约只有一个博弈论的壳子 设 dp[i][j] 表示区间 i ~ j 先手最多能取多少, 它可以由 i ~ j - 1 与 i + 1 ~ j 来转移, 等于上述两个区间 ...
- POJ1861 Network
Time Limit: 1000MS Memory Limit: 30000KB 64bit IO Format: %lld & %llu Description Andrew is ...