zoukankan      html  css  js  c++  java
  • Effective C++ 条款10 令operator=返回一个reference to *this 条款11 在operator=中处理"自我赋值"

    1. 为了支持形如“a=b=c”的连锁形式,最好令operator=返回一个reference to *this.

    2. 如果类中含有用于指向堆内存的指针,那么赋值操作符就要注意自我赋值的问题,例如:

    class A{
    public:
        ...
        A& operator=(const A& tmp){
            if (ptr != tmp.ptr){
                delete ptr;
                ptr = new int(*tmp.ptr);
            }
            return *this;
        }
    private:
        int* ptr;
    };
    View Code

    以上示例虽然已经具备了"自我赋值安全性",但却不具备"异常安全性":如果"new int(*tmp.ptra)"发生异常,被赋值的ptra将指向一个已经被delete的对象,因此为了实现异常安全性,应该保证先赋值再delete,如下:

    class A{
    public:
            ...
        A& operator=(const A& tmp){
            int* temp = ptr;//临时储存ptr的值
            ptr = new int(*tmp.ptr);
            delete temp;
            return *this;
        }
    private:
        int* ptr;
    };
    View Code

     以上保证了异常安全性的同时也保证了自我赋值的安全性,缺点是自我赋值虽然是安全的,但是却进行了不必要的申请内存和复制,如果自我赋值频率确实很高,可以把"证同测试“再次放回函数起始处.

    3. 像上例一样在operator=内部手工排列语句的一个替代方案就是使用所谓的"copy and swap"技术,这个技术和异常安全性有密切关系(见条款29),如下:

    class A{
    public:
        void swap(A& rhs){
            ...
        }
        A& operator=(A tmp){//注意此处按值传递
            A temp(tmp);
            swap(temp);
        }
    private:
        int* ptr;
    };
    View Code

    这样牺牲了清晰性而且比之前的例子多了一次对象构造,但采用按值传递实际上"将'copying'动作从函数本体移至'函数参数构造阶段'",这"可令编译器有时生成更高效的代码".

    4. 不只是赋值操作符,其它函数如果要操作一个以上对象,而其中有些对象可能是同一个时,也要确保函数行为的正确性.

  • 相关阅读:
    七.贪心算法
    六。二叉树
    从git指定commit拉分支
    二分法
    mysql 解决生僻字,特殊字符插入失败
    MYSQL性能优化以及建议
    PDF快捷键
    GC 核心关注点都在这里
    R语言载入包时报错:Error: 程辑包‘survival’没有名字空间
    Centos buff/cache过高
  • 原文地址:https://www.cnblogs.com/reasno/p/4750302.html
Copyright © 2011-2022 走看看