为了在自己定义类里重载一个异常安全(exception safe)的赋值操作符。创造了一个这种习惯用语。也叫:Create-Temporary-and-Swap。

要想写健壮的C++代码。异常安全很重要。

能够给异常安全分三级:

1> 基本安全:实现简单、代价小。应该作为常规手段。

2> 非常安全:在不论什么场合都实现这一步不太可能。本例的赋值操作符重载算是一个。

3> 不抛出异常:能够看non-throwing swap。



所谓“Create-Temporary-and-Swap”。就是先申请新资源。用后再释放。

1> 在申请新资源的时候,要使用RAII原则。

2> 申请成功之后。使用non-throwing swap原则交换资源。

  1. class String {
  2. char * str;
  3. public:
  4. String& operator = (String const &s)
  5. {
  6. String temp (s);    // copy-constructor -- RAII
  7. temp.swap (*this);  // non-throwing swap
  8. return *this;
  9. }
  10. void swap (String &s) throw ()
  11. {
  12. std::swap(this->str, s.str);
  13. }
  14. };

有时会增加对參数的推断:

  1. class String {
  2. char * str;
  3. public:
  4. String& operator = (String const &s)
  5. {
  6. if (this != &s)
  7. String(s).swap (*this); // copy-constructor and non-throwing swap
  8. return *this;
  9. }
  10. void swap (String &s) throw ()
  11. {
  12. std::swap(this->str, s.str);
  13. }
  14. };

在函数内部的暂时变量。事实上能够省略。仅仅要用传值的方式:

  1. String& operator = (String s) // pass-by-value
  2. {
  3. s.swap (*this); // Non-throwing swap
  4. return *this;
  5. }

这样的作法在某些情况下能够得到优化。

假设s绑定到lvalue,无优化。栈内会有暂时对象被创建;假设绑定到rvalue。一般就会省略掉copy ctor的调用。

  1. String createString(); // a function that returns a String object.
  2. String s;
  3. s = createString();    // 这是rvalue的一例。使用传值的赋值操作符。可得到优化

在C++0x标准中,这种赋值操作符叫做“统一赋值操作符”,由于它合“拷贝赋值”、“移动赋值”为一体了。C++0x编译器一旦发现某个类有move ctor存在,总会对暂时的rvalue进行优化的。

老编译器当然没有move ctor,可是能对赋值操作进行rvalue的优化,也算是有的一比。

Copy-and-swap的更多相关文章

  1. c++异常安全和copy and swap策略

    异常安全有两个目标: 不泄露任何资源.这个通过RAII可以做到. 不破坏数据结构.这是下文要讨论的事情 异常安全有三个级别: 基本安全:异常发生后对象和数据结构还有合法状态.实现简单,应该作为最低要求 ...

  2. C++异常安全、copy and swap

    异常安全的代码是指,满足两个条件 1异常中立性 : 是指当你的代码(包括你调用的代码)引发异常时,这个异常 能保持原样传递到外层调用代码.(异常中立,就是指任何底层的异常都会抛出到上层,也就相当于是异 ...

  3. copy and swap技巧与移动赋值操作符

    最近在实现一个Delegate类的时候碰到了一个问题,就是copy and swap技巧和移动赋值操作符有冲突. 比如有以下一个类: class Fun { public: Fun(const Fun ...

  4. 做个地道的c++程序猿:copy and swap惯用法

    如果你对外语感兴趣,那肯定听过"idiom"这个词.牛津词典对于它的解释叫惯用语,再精简一些可以叫"成语".想要掌握一门语言,其中的"成语" ...

  5. c++ swap 函数

    转载地址 1,最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符. template <class T> void swap ( T& a, T& b ) { T ...

  6. [转]谈谈C++中的swap函数

    1,最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符. template <class T> void swap ( T& a, T& b ) { T c(a) ...

  7. [020]转--C++ swap函数

    原文来自:http://www.cnblogs.com/xloogson/p/3360847.html 1.C++最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符 template < ...

  8. 【转】 谈谈C++中的swap函数

    1,最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符. template <class T> void swap ( T& a, T& b ) { T c(a) ...

  9. 【C++ 补习】Copy Control

    C++ Primer 5th edition, chapter 13. The Rule of Three If a class needs a destructor, it almost surel ...

  10. swap function & copy-and-swap idiom

    在C++中,众所周知在一个资源管理类(例如含有指向堆内存的指针)中需要重新定义拷贝构造函数.赋值运算符以及析构函数(Big Three),在新标准下还可能需要定义移动构造函数和移动赋值运算符(Big ...

随机推荐

  1. RVDS 3.1 下载地址及破解方法

    RealView Development Suite 3.1  RVDS 3.1下载地址:https://silver.arm.com/download/Development_Tools/RVDS/ ...

  2. sar使用说明

     sar这东西,一开始还以为是内部有的,原来是外部的工具,可以到 http://pagesperso-orange.fr/sebastien.godard/download.html 去下载 1 安装 ...

  3. 《软件project》课程报告 —国土资源执法监察管理信息系统建模

    ***********************************************声明*************************************************** ...

  4. mongoDB 查询附近的人的语句

    mongoDB 自带LBS查询附近的人 {"location":{ $nearSphere: { $geometry: { type : "Point", co ...

  5. Learning Cocos2d-x for WP8(8)——动作Action

    原文:Learning Cocos2d-x for WP8(8)--动作Action 游戏很大程度上是由动作画面支撑起来的. 动作分为两大类:瞬间动作和延时动作. 瞬间动作基本等同于设置节点的属性,延 ...

  6. PHP移动互联网开发笔记(2)——变量及常量

    原文地址:http://www.php100.com/html/php/rumen/2014/0326/6703.html 一.PHP5.4的基本的语法格式 1.PHP的切割符 view source ...

  7. iOS UITableView的Section Footer加入button

    郝萌主倾心贡献,尊重作者的劳动成果.请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠.支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 在处理UI ...

  8. [jQuery]地图浏览:如何实现图片的放大缩小和点击之后的位置居中

    HTML代码: <!DOCTYPE html> <html> <head> <script src="http://ajax.googleapis. ...

  9. css 实现table 隔行变色

    <html> <head> <title>Member List</title> <style> <!-- .datalist{ bo ...

  10. ACM:回溯,八皇后问题,素数环

    (一)八皇后问题 (1)回溯 #include <iostream> #include <string> #define MAXN 100 using namespace st ...