我偶然发现了一些非常古老的代码,它有一个带有定义的复制赋值运算符的类,它将其参数作为const引用,但也不检查自我赋值,所以基本上:
my_func
将struct A
{
int q;
A(): q(3) {}
A& operator=(const A& a)
{
q = a.q;
return *this;
}
};
的实例分配给自己时,此赋值运算符的行为是什么?我认为这会导致问题,因为它会打破"参数的常量,任何编译器都可以假设参数没有改变并基于此进行优化。
然而clang和gcc都没有发出警告,程序运行正常。如果我在赋值运算符中赋值之前明确地将A
的值更改为4,则此方法也适用。
答案 0 :(得分:20)
将对象绑定到const引用并不会使它突然变为const。 const
仅表示该函数无法通过a
修改参数。它并不意味着被引用的对象必须是const本身。
由于*this
和a
可以合法地为同一个对象设置别名,因此此类代码没有风险。编译器不能对别名做出疯狂的假设。
如果赋值运算符没有运行完成,或者释放资源然后尝试从"其他"中复制,则自我分配只是一个问题。 。你的例子没有发生这种情况的风险。但是,一般情况下,应该注意可能抛出的异常和资源的所有权。