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

  • 相关阅读:
    csuoj 1111: 三家人
    csu oj 1339: 最后一滴血
    csuoj 1337: 搞笑版费马大定理
    csuoj 1334: 好老师
    csu oj 1330 字符识别?
    C++动态内存分配
    变量内存分配
    codevs 2235 机票打折
    contesthunter CH Round #64
    面试分享:一年经验初探阿里巴巴前端社招
  • 原文地址:https://www.cnblogs.com/reasno/p/4750302.html
Copyright © 2011-2022 走看看