在operator=中处理“自我赋值”

什么是自我赋值,非常明显。

就是自己的值赋值给了自己。以下的代码就是自我赋值:

class Widget
{
public:
Widget& operator=(const Widget& rhs)
{
delete p;
p=new int(ths.p);
return *this;
}
int *p;
}; Widget w1,w2;
w1=w2;
w1=w1;//自我赋值。

如上代码,自我赋值的时候会出现删除自身数据的操作,这样非常危急。由于p变成了野指针。

为了防止以上错误能够进行“自我測试”,假设发现是自我赋值就直接返回。

例如以下代码:

class Widget
{
public:
Widget& operator=(const Widget& rhs)
{
if(this==&rhs)//自我測试
return *this;
delete p;
p=new int(rhs.p);
return *this;
}
int *p;
};

可是。以上代码有还有一个缺陷,就是一旦new一个新空间失败,p还是会变成野指针。

所以,能够先保存原来的数据,等new成功之后在进行数据替换;

再次改动代码例如以下:

class Widget
{
public:
Widget& operator=(const Widget& rhs)
{
int tmp=p;//记录原先内存
p=new int(rhs.p);
delete tmp;//释放原先内存
return *this;
}
int *p;
};

Effective C++ 条款11的更多相关文章

  1. Effective C++ 条款11:在operator=中处理"自我赋值"

    "自我赋值"发生在对象被赋值给自己时: class Widget { ... }; Widget w; ... w = w; // 赋值给自己 a[i] = a[j]; // 潜在 ...

  2. Effective C++ 条款11,12 在operator= 中处理“自我赋值” || 复制对象时不要忘记每一个成分

    1.潜在的自我赋值     a[i] = a[j];     *px = *py; 当两个对象来自同一个继承体系时,他们甚至不需要声明为相同类型就可能造成别名. 现在担心的问题是:假如指向同一个对象, ...

  3. Effective C++ -----条款11: 在operator=中处理“自我赋值”

    确保当对象自我赋值时operator=有良好行为.其中技术包括比较“来源 对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap. 确定任何函数如果操作一个以上的对象,而其中多 ...

  4. effective c++ 条款11 Handle assignment to self in operator=

    赋值给自己,听起来有些不可思议,但是却要引起重视,它很容易把自己隐藏起来. 例如 1 a[i]=a[j]; 如果 i, j的值一样? 2 *px=*py; 如果px py指向同一个object 3   ...

  5. effective C++ 读书笔记 条款11

    条款11: 在operator= 中处理"自我赋值" 在实现operator=时考虑自我赋值是必要的就像 x=y .我们不知道变量x与y代表的值是否为同一个值(把x和y说成是一个指 ...

  6. [More Effective C++]条款22有关返回值优化的验证结果

    (这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...

  7. More Effective C++ 条款0,1

    More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...

  8. 《Effective C++ 》学习笔记——条款11

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

  9. Effective C++ 条款08:别让异常逃离析构函数

    1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...

随机推荐

  1. Gentoo Linux 学习笔记1

         Gentoo Linux是一个基于portage进行包管理的Linux发行版,最早版本始于2002年.其官方官网为http://www.gentoo.org 目前,Gentoo Linux已 ...

  2. Delphi使用XmlHttp获取时间

    uses ComObj, DateUtils; procedure TForm1.Button1Click(Sender: TObject); var XmlHttp: Variant; datetx ...

  3. C语言的本质(2)——二进制、八进制、十六进制与十进制

    二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是"逢二进一",借位规则是"借一当二",由18世纪德国数理哲 ...

  4. MultiByteToWideChar和WideCharToMultiByte用法详解, ANSI和UNICODE之间的转换

    //========================================================================//TITLE://    MultiByteToW ...

  5. mysql 存储过程 动态sql例子

    proc:BEGIN ; ; ; ) DEFAULT ''; ) DEFAULT ''; ) DEFAULT '';#插入日志的表,一个活动一张表 #将局部变量转换成会话变量 #动态sql语言只接受会 ...

  6. db2 for linux

    https://www6.software.ibm.com/sdfdl/v2/regs2/db2pmopn/db2_v101/expc/Xa.2/Xb.aA_60_-idYiSFeSuWlF5-w4v ...

  7. AndroidUI 布局动画-点九PNG技术

    下面是正常情况与使用点9切图以后的效果对比: <Button android:id="@+id/button1" android:layout_width="fil ...

  8. Mac/ios 模拟器 测试模拟慢网速

    原文:http://www.heyuan110.com/2015/06/16/Mac%E6%B5%8B%E8%AF%95%E6%A8%A1%E6%8B%9F%E6%85%A2%E7%BD%91%E9% ...

  9. vmlinux,vmlinuz,bzimage,zimage,initrd.img的区别与联系

    1.vmlinux vmlinux是未压缩的内核,vmlinux 是ELF文件,即编译出来的最原始的文件.用于kernel-debug,产生system.map符号表,不能用于直接加载,不可以作为启动 ...

  10. 第二章SignalR所支持的平台

    第二章SignalR所支持的平台 SignalR支持各种服务器和客户端的配置.此外,每种传输方式都有自身的配置要求和限制:如果某种传输方式不被系统支持,SignalR优雅地将故障转移到其他类型的传输方 ...