使用const ref参数进行自我赋值的行为

Mar*_*zog 8 c++ c++98

我偶然发现了一些非常古老的代码,它有一个带有定义的复制赋值运算符的类,它将其参数作为const引用,但也不检查自赋值,所以基本上:

struct A
{
    int q;
    A(): q(3) {}

    A& operator=(const A& a)
    {
        q = a.q;
        return *this;
    }
};
Run Code Online (Sandbox Code Playgroud)

当一个实例A被赋给自己时,这个赋值运算符的行为是什么?我认为这会导致问题,因为它"破坏"参数的常量,任何编译器都可以假设参数没有改变并基于此进行优化.

然而,clang和gcc都没有发出警告,程序运行正常.如果我q在赋值运算符中赋值之前显式将值更改为4,这也可以工作.

Sto*_*ica 20

将对象绑定到const引用并不会使它突然变为const.在const那里只表示该功能无法通过修改参数a.这并不意味着引用的对象必须是const本身.

由于*this并且a可以合法地对同一个对象进行别名,因此这些代码没有风险.编译器不能对别名做出疯狂的假设.

如果赋值运算符没有运行完成,或者释放资源然后尝试从"其他"复制,则对象状态可能会以某种方式损坏,自我分配只是一个问题.你的例子没有发生这种情况的风险.但总的来说,应该注意可能抛出的异常和资源的所有权.