• Copy-and-swap


    为了在自己定义类里重载一个异常安全(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的优化,也算是有的一比。

  • 相关阅读:
    Java内存泄漏的排查总结
    多文本匹配 AC算法(Aho-Corasick)
    Linux下进程管理利器—supervise(监控并将死掉的程序重启)
    maven pom项目的dependencies转gradle格式
    Protocol Buffers官方文档(开发指南)
    Spring的工具类StringUtils使用
    springboot2 中Druid和ibatis(baomidou) 遇到org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.iflytek.pandaai.service.multi.mapper.TanancyMapper
    gradle 多模块Springboot项目 compile project引用其他模块的坑
    JAVA 运行springboot jar包设置classpath
    mysql8
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5069246.html
Copyright © 2020-2023  润新知