条款10:令operator=返回一个reference to *this

为了实现“连锁赋值”,赋值操作符必须返回一个reference指向操作符的左侧实参,这是你为classes实现赋值操作符时应该遵循的协议。

class Widget{
public:
...
Widget& operator+=(const Widget& rhs) //同样适用于-=, *=
{
...
return *this;
} Widget& operator=(const Widget& rhs) //同样适用于-=, *=
{
...
return *this;
} Widget& operator=(int rhs) //此函数也是和,即使此一操作符参数类型不符合协定
{
...
return *this;
}
};

注意,这只是一个协议,并无强制性。如不遵循它,代码一样可以通过编译。然而这份协议被所有内置类型和标准程序库提供的类型工作遵守(string vector  complex tr1::shared_ptr)

请记住:

  • 令赋值操作符(assignment)操作符返回一个reference to *this

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

1、一般而言,如果某段代码操作pointers或references而它们被用来“指向多个相同类型”,就需要考虑这些对象是否为同一个。实际上,两个对象只要来自同一个继承体系,甚至不需要声明为相同类型就可能造成“别名”(应为base class的指针或引用可以指向一个derived)。如:

a[i] = a[j] //若i与j具有相同的值,这便是自我赋值;

*px = *py//如果px与py恰巧指向同一个对象,则时自我赋值

void doSomething(const Base& rb, Derived* pd);//若rb与rp可能指向同一个对象

2、如果遵循条款13和14的忠告,你会运用对象来管理资源,而且你可以确定所谓“资源管理对象”在copy发生时有正确的举措。在这种情况下你的赋值操作符或许是“自我赋值安全的”(self-assignment-safe),不需要额外操心

3、如下代码,在自我赋值时会会抛出异常

class Bitmap { ... };
class Widget
{
...
private:
Bitmap* pb;
}; Widget& Widget::Operator=(const Widget& rhs)
{
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}

这里若是自我复制问题是,operator=函数内的*this和rhs有可能是同一对象;若是如此delete就不只是销毁当前对象的bitmap,也销毁了rhs的bitmap

Widget& Widget::operator=(const Widget& rhs)
{
if(this == &rhs) return *this;
delete pb;
pb = new Bitmap(*rhs.pb);
return *this;
}

如此在赋值前进行一个“认同测试(identify test)”达到自我赋值的检验目的

但是此段代码不具备“异常安全性”,在new Bitmap导致异常(不论是因为分配时内存不足或因为Bitmap的copy构造函数抛出异常),Widget最终会持有一个指针指向一块被删除的Bitmap。

最新文章

  1. POCO Controller 你这么厉害,ASP.NET vNext 知道吗?
  2. 内外分离接口依赖及UIScrollView知识点
  3. C#指定日期为一年中的第几周
  4. PHP限制HTML内容中图片必须是本站的方法
  5. POJ--1416
  6. 【Go】 http webserver
  7. SQL 2008 R2 启动失败 提示 请求失败或服务未及时响应
  8. 利用wireshark抓取Telnet的用户名和密码
  9. TSS 任务状态段
  10. 使用CLK.AspNet.Identity提供以角色为基础的访问控制(RBAC)
  11. Struts2 校验
  12. C# 异步Socket
  13. NDK-gdb的错误ERROR(不同于上一篇): Could not extract package's data directory...的解决方法
  14. Vuejs实例-01使用vue-cli脚手架搭建Vue.js项目
  15. CSIS 1119B/C Introduction to Data Structures and Algorithms
  16. C++实现程序单实例运行的两种方式
  17. 微信小程序开发注意事项总结:上拉加载失效、转义字符等
  18. 拼接字符串,生成tree格式的JSON数组
  19. 获取CNVD的cookie
  20. servlet请求中的信息

热门文章

  1. python3 虚拟环境的创建
  2. k8s-traefik默认80端口
  3. varnish 子程序流程
  4. HTML练习二--动态加载轮播图片
  5. VBA学习资料分享-3
  6. luogu P3750 [六省联考2017]分手是祝愿
  7. Java日志规范(转载)
  8. 字节流、字符串、16进制字符串转换__java
  9. You are using the runtime-only build of Vue where the template compiler is not available.
  10. 使用代码将github仓库里某个issue同步到CSDN博客上