C++ 默认分配运算符检查自分配

C++ 默认分配运算符检查自分配,c++,operators,standards,C++,Operators,Standards,我想知道赋值运算符的默认实现是否检查自赋值,因此这两个实现中哪一个可以被视为最接近默认实现: 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&

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

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++标准,但是我能找到的唯一的是,但是关于这个< /p>

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

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

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

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


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


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

该描述并不排除默认生成的实现执行自我分配检查的可能性。标准并没有阻止它。唯一可以确定的方法是实际查看编译器生成的代码。@RemyLebeau标准说,“非联合类X的隐式定义的复制/移动赋值运算符对其子对象执行成员态复制/移动赋值。”这如何允许实现检查自赋值?标准还包括“防止“可变长度数组和灵活的数组成员。取出内容是一种不好的形式,但人们似乎总是在添加内容。@1201程序设计标准只是说生成的操作符执行单个成员的复制/移动分配。它并不是说,如果需要,操作符实现也不能首先检查自分配。