• C++进阶--处理拷贝赋值运算符中自赋值的情况


    //############################################################################
    /*
     * 处理拷贝赋值运算符=中自赋值的情况
     *
     *
     * 运算符重载: 利用人们的直觉,减少学习曲线
     */
    // 自赋值的情况
    dog dd;
    dd = dd;  // 看起来很傻
    
    dogs[i] = dogs[j]; // 看起来不怎么傻
    
    
    /* 实现赋值运算符 */
    class collar;
    class dog {
       collar* pCollar;
       dog& operator=(const dog& rhs) {
          if (this == &rhs)
             return *this;
    
          collar* pOrigCollar = pCollar;  
          pCollar = new collar(*rhs.pCollar); //可能会失败,保证异常安全
          delete pOrigCollar;
          return *this;
       }
    }
    
    
    /* 实现 2: 委托 */
    class dog {
       collar* pCollar;
       dog& operator=(const dog& rhs) {
          *pCollar = *rhs.pCollar;   // 逐成员拷贝collar,或者调用collar的拷贝赋值运算符=
          return *this;
       }
    }
    
    /* 实现 3:copy and swap 
    -- C++中析构函数和swap时强异常安全的
    拷贝构造生成一个临时对象,然后跟本对象swap
    异常安全,且天然解决了自赋值问题
    注意swap的可见性问题
    */
    class dog {
       collar* pCollar;
       dog& operator=(const dog& rhs) {
          dog tmp_dog(rhs);
          this->swap(tmp_dog);
          return *this;
       }
    }
    //成员函数的方式
    void dog::swap(dog& rhs) {
        using std::swap;
        //swap(this->pCollar, rhs->pCollar);
        this->pCollar->swap(rhs->pCollar);
        
    }
    
    //非成员函数的方式 模板全特化
    namespace std {
        template<>
        void swap<dog> (dog& lhs, dog& rhs)
        {
            lhs.swap(b);
        }
    }
    
  • 相关阅读:
    线程池
    单例设计模式
    String,StringBuffer,StringBuilder
    马踏棋盘算法
    最短路径问题 (迪杰斯特拉算法,弗洛伊德算法)
    最小生成树 修路问题(普里姆算法,克鲁斯卡尔算法)
    贪心算法 求解集合覆盖问题
    Stream 数组转换
    unittest与pytest对比
    条件编译
  • 原文地址:https://www.cnblogs.com/logchen/p/10165423.html
Copyright © 2020-2023  润新知