【问题标题】:Default assignment operator checks for self assignment默认赋值运算符检查自赋值
【发布时间】:2020-02-18 21:14:29
【问题描述】:

我想知道赋值运算符的默认实现是否检查自赋值,那么这两个实现中的哪一个可以被认为最接近默认实现:

class A{
    int x;
public :
    ...
    // first one
    A& operator=(const A& a){
        if(this != &a) x = a.x;
        return *this;
    }
    // second one
    A& operator=(const A& a){
        x = a.x;
        return *this;
    }
}

我已经搜索过 C++ 标准,但我能找到的唯一一个是 this,但对此一无所知

【问题讨论】:

    标签: c++ operators standards


    【解决方案1】:

    不,实现不检查“自我”:

    https://en.wikipedia.org/wiki/Assignment_operator_(C%2B%2B)

    复制赋值运算符,通常简称为“赋值 运算符”,是赋值运算符的一种特殊情况,其中源 (右侧)和目的地(左侧)相同 类类型。

    它是特殊的成员函数之一,这意味着 它的默认版本是由 如果程序员没有声明一个编译器。

    默认版本 执行 memberwise 复制,其中每个成员都由自己的成员复制 复制赋值运算符(也可以是程序员声明的或 编译器生成)。

    【讨论】:

    • 该描述不排除默认生成的实现执行自分配检查的可能性。标准并没有阻止它。唯一确定的方法是实际查看编译器生成的代码。
    • @RemyLebeau 该标准说,“非联合类 X 的隐式定义的复制/移动赋值运算符执行其子对象的成员复制/移动赋值。”这如何允许实现检查自分配?
    • 该标准还“阻止”了可变长度数组和灵活的数组成员。取出东西是不好的形式,但人们似乎总是在添加东西。
    • @1201ProgramAlarm 该标准仅表示生成的运算符执行各个成员的复制/移动分配。它并不是说如果它愿意,操作符实现也不能首先检查自赋值。
    【解决方案2】:

    赋值运算符不检查自赋值。因此,您的第二个实现最接近默认实现。

    我在标准中看不到任何关于任何此类优化的词,如果在某些情况下我的类的属性不会由编译器生成的运算符分配,那会很奇怪。想象一下,某些属性分配是用户定义的,并且执行了一些不常见的任务。编译器不知道这一点,即使我为自己分配一个对象,IMO 也应该调用它们。

    【讨论】:

      猜你喜欢
      • 2013-08-09
      • 2011-08-02
      • 2012-11-26
      • 1970-01-01
      • 2015-02-25
      • 1970-01-01
      • 2019-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多