条款11:在operator=中处理“自我赋值”
什么是自我赋值,就是 v = v 这种类型的语句,也许很多人都会说鄙视这种写法,但是如下的写法会不会出现呢?
比如:a[i] = a[j]; // 不巧的是i可能和j相等
*px = *py; // 也许px和py刚好指向同一个对象呢
上述例子都是隐含的自我赋值。
再举一例:
1 class Bitmap // 位图类 2 { 3 ... 4 }; 5 6 class Widget 7 { 8 public: 9 Widget& operator=(const Widget& rhs); 10 11 private: 12 Bitmap* pb; // 指向动态分配的位图对象 13 }; 14 15 Widget& Widget::operator=(const Widget& rhs) 16 { 17 delete pb; // 释放当前位图对象 18 pb = new Bitmap(*rhs.pb); // 使用rhs中位图的副本 19 return *this; 20 }
现在假设*this和rhs是同一个对象呢?那么delete的调用就会释放*this的位图,其实同时也释放了rhs的位图资源,那么此时=的意义就变成了:让一个指针指向一个已被删除的对象,太可怕了。还好如下做法可以解决这个错误,被称为identity test:
Widget& Widget::operator=(const Widget& rhs) {if(this == &rhs) // identity testreturn *this; // 如果是同一个对象则返回即可else{delete pb; // 释放当前位图对象pb = new Bitmap(*rhs.pb); // 使用rhs中位图的副本return *this;} }
一个更好的赋值方案是使用copy and swap技术,如下所示:
1 class Widget 2 { 3 ... 4 void swap(Widget& rhs); // 交换*this和rhs的内容 5 ... 6 }; 7 8 Widget& Widget::operator=(const Widget& rhs) 9 { 10 Widget temp(rhs); // 制作一个rhs的副本 11 swap(temp); // 将该副本内容和*this交换 12 return *this; 13 }
转载于:https://www.cnblogs.com/benxintuzi/p/4530556.html
条款11:在operator=中处理“自我赋值”相关推荐
- 条款11 在operator=中处理“自我赋值”
"自我赋值"发生在对象被赋值给自己时: 1 class Widget {...}; 2 Widget w; 3 ... 4 w = w; //赋值给自己 这看起来有点愚蠢,但它合法 ...
- Effective C++ 11 在operator=中处理“自我赋值” 笔记
"自我赋值"发生在对象被赋值给自己时: 1 class Widget {...}; 2 Widget w; 3 ... 4 w = w; //赋值给自己 这看起来有点愚蠢,但它合法 ...
- Effective C++ 条款11:在operator=中处理自我赋值
"自我赋值"发生在对象被赋值给自己时: class Widget { ... }; Widget w; ... w = w; // 赋值给自己 a[i] = a[j]; // 潜在 ...
- EC笔记:第二部分:11:在operator=中处理“自我赋值”
已经一年半没有写过博客了,最近发现学过的知识还是需要整理一下,为知笔记,要开始收费了以前写在为知笔记上笔记也会慢慢的转到博客里. 话不多说,进入正题. 考虑考虑以下场景: 当某个对象对自身赋值时,会出 ...
- C++尽量在operater=中处理“自我赋值”
operater=中处理"自我赋值 下面的operator=实现是一份不安全的实现,在自赋值时会出现问题: 1.在开头添加"证同测试" c++ 2.通过确保异常安全来获得 ...
- effective C++ 条款 11:在operator= 处理‘自我赋值’
假设建立一个class来保存一个指针指向一块儿动态分配的位图(bitmap) class Bitmap{...}; class Widget { public: protected: private: ...
- 在operator =中要处理“自我赋值”
防止自我赋值很有必要 Widget w; w = w; a[i] = a[j]; //a[i]和a[j]实际上指向同一个元素 *pi = *pj; //pi和pj实际上指向同一个元素 自我赋值的危害: ...
- C++中对象初始化赋值是否需要调用operator=函数
一般对于初始化类变量有两种方式: A a; A b = a; 另一种方式是: A a ; A b; a =b; 对于第一种方式,编译器相当于在b的初始化的时候,用a的引用作为复制构造函数的参数进行操作 ...
- 条款15: 让operator=返回*this的引用
C++的设计者Bjarne Stroustrup下了很大的功夫想使用户自定义类型尽可能地和固定类型的工作方式相似.这就是为什么你可以重载运算符,写类型转换函数(见条款M5),控制赋值和拷贝构造函数,等 ...
最新文章
- eclipse mybatis插件_Archetype插件的介绍和使用
- ubuntu 14.04 安装chrome及给chromium 安装 flash player
- 深入学习SAP UI5框架代码系列之二:UI5 控件的渲染器
- “约见”面试官系列之常见面试题之第七十五篇之vue中如何使当前css起作用(建议收藏)
- 前端学习(1880)vue之电商管理系统电商系统之获取左侧菜单数据
- 解密android日志xlog,XLog 详解及源码分析
- 李礼辉:如何进行必要的数字金融制度建设等问题值得关注
- Jvm内存分析入门篇
- python语言的变量随时_python的变量和简单的数据类型
- VMware Server1.03下载地址及序列号
- 算法:动态规划解决爬楼梯Climbing Stairs python3
- 内存数据库fastdb的使用研究报告
- 芯驰任命程泰毅为CEO:张强和仇雨菁分别担任CMO和COO
- C/C++编程题之简单密码
- 本质安全设备标准(IEC60079-11)的理解(一)
- 【问题】【实用】java服务假死【CLOSE_WAIT】【线程WAITING】
- dataguard 日志的应用
- WSL / WSL2 问题大全 及 解决方案
- Windows:通过GPO部署iTunes for Windows
- Python :字符串,常用函数。list常用函数,方法。
热门文章
- 未能加载文件或程序集“System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依
- iOS学习08代码1
- 洛谷 P5459 [BJOI2016]回转寿司 【CDQ分治】
- 机器学习编译入门课程学习笔记第二讲 张量程序抽象
- 个人学习笔记——庄懂的技术美术入门课(美术向)07
- JAVA访问修饰符限制性最高的_问:JAVA中,访问修饰符限制性最高的是protected ( )...
- 明星直播的品牌效应,这几个关键数据你一定要知道!
- 强大的密码破解工具:hashcat简介与用法介绍与实例
- 模块讲解——time,datetime,json,os,requests
- GEE遥感云大数据在林业中的应用