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

8

我偶然发现了一些非常老的代码,其中一个类定义了复制赋值运算符,它将参数作为const引用,但也没有检查自我赋值,因此本质上是:

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

    A& operator=(const A& a)
    {
        q = a.q;
        return *this;
    }
};

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

然而,无论是clang还是gcc都没有发出警告,程序也可以正常运行。如果在赋值运算符中的赋值之前明确更改q的值为4,则此方法也有效。


值得注意的是,在这种情况下,参数确实没有被改变。 - Lightness Races in Orbit
1个回答

20

将对象绑定到const引用并不会突然使其变为const。这里的const仅表示函数无法通过a修改参数。它并不意味着所引用的对象本身必须是const。

由于*thisa可以合法地别名同一对象,因此在这种代码中没有风险。编译器不能对别名做出荒谬的假设。

当对象状态可能在赋值运算符未能完成时被留下破损时,自我赋值才是一个问题,或者释放了它接着尝试从“其他”复制资源。你的例子没有发生这种风险。不过,通常应注意潜在抛出异常和资源所有权问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接