我偶然发现了一些非常古老的代码,它有一个带有定义的复制赋值运算符的类,该运算符将其参数作为常量引用,但也不检查自赋值,因此本质上:
struct A
{
int q;
A(): q(3) {}
A& operator=(const A& a)
{
q = a.q;
return *this;
}
};
当 A
的一个实例被赋值给它自己时,这个赋值运算符的行为是什么?我认为这会导致问题,因为它“破坏”了参数的常量性,任何编译器都可以假设参数没有更改并基于此进行优化。
然而,clang 和 gcc 都没有发出警告,程序运行正常。如果我在赋值运算符中赋值之前将 q
的值显式更改为 4,这也有效。
最佳答案
将对象绑定(bind)到 const 引用并不会突然使它成为 const。那里的const
只是表示函数不能通过a
修改参数。这并不意味着所引用的对象必须是 const 本身。
因为 *this
和 a
可以合法地为同一个对象起别名,所以这样的代码没有风险。编译器不能对别名做出大胆的假设。
自赋值只是一个问题,如果赋值运算符没有运行完成,对象状态可能会以某种方式被破坏,或者释放资源然后尝试从“其他”复制。您的示例没有发生这种情况的风险。但是,一般来说,应该注意可能抛出的异常和资源的所有权。
关于c++ - 带有 const ref 参数的自赋值行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49146481/