Effective C++ Item 10,11 Have assignment operators return a reference to *this Handle assignment to self in operator =
If you want to concatenate assignment like this
int x, y, z;
x = y = z = 15;
The convention is to make the assignment operators return a reference to *this.
11 Handle assignmnet to self in operator =
You can easily assign an object to itself without knowing it
// Example 1
Foo *px, *py;
px = py; //Example 2
a[i] = a[i];
It is dangerous to assign an object to self if your class doesn't handle this kind of opeator appropriately. Let's consider an example here:
class Bitmap{...};
class Widget {
...
private:
Bitmap *m_pb;
};
Widget& Widget::operator=(const Widget& rhs) {
delete m_pb;
m_pb = new Widget(rhs);
return *this;
}
You will be dead if you assign an object to itself, beacause you will end up holding a pointer to a deleted object!
One way but not the best way to deal with self assignment is to write code to explicitly deal with this situation:
Widget& Widget::operator=(const Widget& rhs) {
if(this == &rhs) {
return *this;
}
delete m_pb;
m_pb = new Bitmap(*rhs).m_ph;
return *this;
}
This is not the best way because above this operator is not exception-safe. What does that mean? Imagine what if an exception is thrown when
ph = new Bitmap(*rhs.m_ph)
is been executed(for example, not enough memory), then the object will hold a pointer to a deleted object.
Luckily, making operator= safe renders it self-assignmnet-sage, too. So, the best way to accomplish that is:
Widget& Widget::operator=(const Widget& rhs) {
Bitmap* tmp = m_pb;
pb = new Bitmap(*rhs.m_pb);
delete tmp;
return *this;
}
Now if "new Bitmap" throw an exception, pb remains unchanged. Even without the identity test, this code handle assignment to self, because we make a copy of the original bitmap, point to the copy we made, and then delete the original Bitmap.
A more straightforward way to do so is to use exception-safe function swap
Widget& Widget::operator=(const Widget& ths) {
Widget temp(ths);
swap(temp);
return *this;
}
Effective C++ Item 10,11 Have assignment operators return a reference to *this Handle assignment to self in operator =的更多相关文章
- 条款10:令operator=返回一个reference to * this(Have assignment operators return a reference to *this)
NOTE: 1.令赋值(assignment)操作符返回一个reference to *this. 2.此协议适用于所有赋值相关的运算比如:+= -= *=....
- Effective JavaScript Item 10 避免使用with
本系列作为Effective JavaScript的读书笔记. Item 9:避免使用withkeyword 重点: 设计withkeyword本来是为了让代码变简洁,可是却起到了相反的效果.比方: ...
- 读书笔记 effective c++ Item 10 让赋值运算符返回指向*this的引用
一个关于赋值的有趣的事情是你可以将它们链在一起: int x, y, z; x = y = z = ; // chain of assignments 同样有趣的是赋值采用右结合律,所以上面的赋值链被 ...
- <Effective C++>读书摘要--Ctors、Dtors and Assignment Operators<二>
<Item 9> Never call virtual functions during construction or destruction 1.you shouldn't call ...
- <Effective C++>读书摘要--Ctors、Dtors and Assignment Operators<一>
<Item 5> Know what functions C++ silently writes and calls 1.If you don't declare them yoursel ...
- 读书笔记 effective c++ Item 11 在operator=中处理自我赋值
1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: class Widget { ... }; Widget w; ... w = w; // assignment to sel ...
- 读书笔记 effective c++ Item 5 了解c++默认生成并调用的函数
1 编译器会默认生成哪些函数 什么时候空类不再是一个空类?答案是用c++处理的空类.如果你自己不声明,编译器会为你声明它们自己版本的拷贝构造函数,拷贝赋值运算符和析构函数,如果你一个构造函数都没有声 ...
- 读书笔记 effective c++ Item 12 拷贝对象的所有部分
1.默认构造函数介绍 在设计良好的面向对象系统中,会将对象的内部进行封装,只有两个函数可以拷贝对象:这两个函数分别叫做拷贝构造函数和拷贝赋值运算符.我们把这两个函数统一叫做拷贝函数.从Item5中,我 ...
- Java基础-赋值运算符Assignment Operators与条件运算符Condition Operators
Java基础-赋值运算符Assignment Operators与条件运算符Condition Operators 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.赋值运算符 表 ...
随机推荐
- CallableStatement简单使用
直接上存储过程.函数 --运行不带參数但带返回值的存储过程 CREATE OR REPLACE PROCEDURE proc_getUserCount(v_totalCount OUT NUMBER) ...
- RabbitMQ php 使用
RabbitMQ是一个开源的基于AMQP(Advanced Message Queuing Protocol)标准,并且可靠性高的企业级消息系统,目前很多网站在用,包括reddit,Poppen.de ...
- [转]sql:除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询
执行sql语句: select * from ( select * from tab where ID>20 order by userID desc ) as a order by date ...
- Ubuntu 16.04下搭建kubernetes集群环境
简介 目前Kubernetes为Ubuntu提供的kube-up脚本,不支持15.10以及16.04这两个使用systemd作为init系统的版本. 这里详细介绍一下如何以非Docker方式在Ubun ...
- find_if查找vector内对象的成员 作为菜鸟一直不会用也不敢用
用stl的find方法查找一个包含简单类型的vector中的元素是很简单的,例如 vector<string> strVec; find(strVec.begin(),strVec.end ...
- ubuntu下将CapsLock改为Ctrl键
需求:Ubuntu下用Vim时,ESC因为在左上角,还算是好按,但是Ctrl就太坑了,在左右两个下角,实在是太不方便了. 经过分析决定将:CapsLock键改为Ctrl,但仍然保留下面的原Ctrl键( ...
- (Xilinx)FPGA中LVDS差分高速传输的实现
https://wenku.baidu.com/view/24e8bad86f1aff00bed51ef8.html
- [svc]salt安装lamp
在批量安装软件前,先找台测试机yum装一遍,看是否报错等,是否依赖包全等 . 本次我们在dev环境下搞. 先看一下已搞成功的目录结构 定义dev环境的第二个好处 搞清楚逻辑结构和调用关系很重要,不然之 ...
- tracert路由跟踪工具使用方法
1. 路由跟踪在线Tracert工具说明 Tracert(跟踪路由)是路由跟踪实用程序,用于确定 IP 数据报访问目标所采取的路径.Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP ...
- 0067 MySQL的日期字段的取值用单引号
这两天在做sql练习题http://www.cnblogs.com/zxx193/p/4000467.html的时候,涉及到下面的建表+插数据操作 CREATE TABLE t1( s_no VARC ...