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. ...
随机推荐
- (转)iOS 属性字符串
富文本的基本数据类型是NSAttributedString.**属性化字符串**(attributed string)是把属性设置到某些字符上的字符串.属性可以是任何键值对,但是为了实现富文本,则通常 ...
- LeetCode(119) Pascal's Triangle II
题目 Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [ ...
- stm32L011F3——串口实例
/* STM32L0xx HAL library initialization: - Configure the Flash prefetch, Flash preread and Buffer ca ...
- 快速入门Sklearn
主要确定sklearn的基本流程,然后把sklearn当做螺丝刀来用就行了,需要什么查什么. 基本流程 首先我们回顾一下机器学习的基本流程: 特征工程,包括了数据清洗,数据标准版化,特征选取,特征降维 ...
- Android开发工具——Gradle知识汇总
1.什么是构建工具 Eclipse大家都知道是一种IDE(集成开发环境),最初是用来做Java开发的,而Android是基于Java语言的,所以最初Google还是希望Android能在Eclipse ...
- ZOJ 3469 区间DP Food Delivery
题解 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm ...
- C#学习基础概念二十五问
C#学习基础概念二十五问 1.静态变量和非静态变量的区别?2.const 和 static readonly 区别?3.extern 是什么意思?4.abstract 是什么意思?5.internal ...
- linux下连接到远程主机,用图像界面(想在远程服务器上用cmake)
1. 需要通过SSH -X username@ip登陆服务器后,再用图形界面,比如用cmake 2.直接用 SSH username@ip命令登陆服务器后,不能用cmake
- HDU-1392 Surround the Trees,凸包入门!
Surround the Trees 此题讨论区里大喊有坑,原谅我没有仔细读题还跳过了坑点. 题意:平面上有n棵树,选一些树用绳子围成一个包围圈,使得所有的树都在这个圈内. 思路:简单凸包入门题,凸包 ...
- JS 调用存储过程传递参数
引用 #region 程序集 Newtonsoft.Json.dll, v4.5.0.0 // E:\Newtonsoft.Json.dll #endregion public DataTable R ...