防止自我赋值很有必要

Widget w;
w = w;
a[i] = a[j]; //a[i]和a[j]实际上指向同一个元素
*pi = *pj; //pi和pj实际上指向同一个元素

自我赋值的危害

Widget
{
private:
Test *p;
};
Widget &Widget::operator=(const Widget &w)
{
delete p;
p = new int (*w.p);
return *this;
}

如果是自我赋值,会把自己的空间释放掉,即当执行delete p后,w.p已经指向一个被释放的内存空间(此时*w.p的内容未知);当执行 p = new int(*w.p);即让p重新指向一个存储了(*w.p)的内存空间,该内存空间内容又是未知的。当再次引用时,会出现未定义的行为。

改良版本

Widget &Widget::operator=(const Widget &w)
{
if (this == &w)
{
return *this;
}
delete p;
p = new Test(*w.p);
return *this;
};

这个类虽然能避免自我赋值的问题,但是,如果new Test时抛出异常,那么Widget最终会持有一个指针指向一块被删除的内存区域,这样的指针是有害的。

改成这样

Widget &Widget::operator=(const Widget &rhs)
{
Test *porg = p;
p = new Test(*rhs.p);
delete porg;
return *this;
}

此时new Test发生异常,那么p可以保持原状。(异常发生的时候,不会给p赋值)

delete prog;保证了p原来指向的内存空间也会被顺利释放。

在operator =中要处理“自我赋值”的更多相关文章

  1. 条款十七: 在operator=中检查给自己赋值的情况

    在赋值运算符中要特别注意可能出现别名的情况,其理由基于两点.其中之一是效率.如果可以在赋值运算符函数体的首部检测到是给自己赋值,就可以立即返回,从而可以节省大量的工作,否则必须去实现整个赋值操作. 另 ...

  2. 条款11:在operator=中处理“自我赋值”

    什么是自我赋值,就是 v = v 这种类型的语句,也许很多人都会说鄙视这种写法,但是如下的写法会不会出现呢? 比如:a[i] = a[j];      // 不巧的是i可能和j相等 *px = *py ...

  3. 【11】在operator=中处理“自我赋值”

    1.自我赋值,看起来愚蠢,但是却合法.有些自我赋值一眼就可看出来.有些自我赋值是潜在的.比如:a[i] = a[j]; *px = *py; 甚至不同类型的指针,都指向同一个地址,也是自我赋值,这一类 ...

  4. 读书笔记 effective c++ Item 11 在operator=中处理自我赋值

    1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: class Widget { ... }; Widget w; ... w = w; // assignment to sel ...

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

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

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

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

  7. [Effective C++ --011]在operator=中处理“自我赋值”

    一.何谓“自我赋值”? 1.1.场合一 直接赋值 w = w; 1.2.场合二 同一数组         a[i] = a[j]: 1.3.场合三 指针         *px = *py: 1.4. ...

  8. EC读书笔记系列之6:条款11 在operator=中处理自我赋值

    记住: ★确保当对象自我赋值时operator=有良好行为.有三种方法:比较“来源对象”和“目标对象”的地址.精心周到的语句顺序.以及copy-and-swap技术 ★确定任何函数若操作一个以上对象, ...

  9. Effective C++_笔记_条款11_在operator=中处理“自我赋值”

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 为什么会出现自我赋值呢?不明显的自我赋值,是“别名”带来的结果: ...

随机推荐

  1. SonarQube(代码质量管理)环境搭建

    继 Centos6.6安装Subversion版本控制工具(Subversion + Apache + jsvnadmin) 后,搭建代码质量管理环境 IP:10.0.210.112 环境:Cento ...

  2. java-map复合类型(HashMap-TreeMap)常用操作例子(适合初学者)

    package com.net.xinfang.reflect; import java.util.ArrayList; import java.util.HashMap; import java.u ...

  3. javascript的作用域和闭包(三)闭包与模块

    一些很重要的说明:前面三篇博客详细的介绍了,引擎与编译器和作用域的关系,重点需要理解的是编译器中的分词与词法分析,JavaScript的特有的“赋值操作的左右侧”引用操作:编译阶段的词法作用域的工作原 ...

  4. ArcGis Python脚本——批量对影像、要素类定义投影

    这一段是批量定义要素类(FeatureClasses)投影的ArcPy代码: 把要处理的要素类塞进一个文件夹(工作空间,workspace),然后将代码开头的路径换成这个“文件夹”的路径,处理完后再做 ...

  5. weblogic安装错误记录

    问题1:/opt/oraInventory路径无效(无法读取/写入/执行) 查看目录权限,发现此目录属于dba,如果用这个目录的话,可能会覆盖掉Oracle数据库相关的东西 再参照weblogic静默 ...

  6. tomcat cluster session同步时保存map数据遇到的问题

    Tomcat Cluster官网:https://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html(tomcat7.0) 场景: tomcat1 ...

  7. C# using 的用法

    Ø  前言 说起 C# using 语句,想必大家都不陌生,它是 C# 中关键字之一.我们基本每天写代码都会使用到,其实也非常简单. 1.   首先,说说 using 有哪些用途 1)   用于引用其 ...

  8. iOS快捷代码块

    //数据请求 /**<#封装数据请求(只适用本人)#>*/ NSString * requestUrl = [NSString stringWithFormat:@"%@%@&q ...

  9. 【Django】git建仓上传时遇到的小问题

    根据教程 http://tutorial.djangogirls.org/zh/deploy/,在github上建仓上传项目文件. 执行到 git push -u origin master 时,输入 ...

  10. Ubuntu中安装python3.6(转)

    因为TensorFlow只支持到python3.6,所以安装python3.6版本 Python3.6的使用越来越普遍.Ubuntu16.04的版本中默认胸自带python2和python3.5的版本 ...