C++为什么赋值运算符应该返回一个const ref以避免(a = b)= c

ant*_*wrx 26 c++ operator-overloading assignment-operator

我正在读一本关于C++的书,更确切地说是关于运算符重载的书.

示例如下:

const Array &Array::operator=(const Array &right)
{
// check self-assignment
// if not self- assignment do the copying
return *this; //enables x=y=z
}
Run Code Online (Sandbox Code Playgroud)

本书提供的关于返回const ref而不是ref的解释是为了避免诸如(x = y)= z之类的赋值.我不明白为什么要避免这种情况.我知道在这个例子中首先计算x = y,因为它返回一个const引用,所以不能执行= z部分.但为什么?

Ash*_*unn 28

(x=y)表示x.operator=(y)返回对象的x.因此,(x=y)=z意味着(x.operator=(y)).operator=(z).parens中的表达式设置xy并返回x,然后外部位设置xz.它不设置yz如你所料,并作为表达x = y = z一样.

这种行为是违反直觉的(在分配后它们应该都是平等的,对吧?); 返回一个const引用使它成为不可能并避免问题.

  • 谁会期望`(x = y)= z`将`y`设置为`z`?这是一个非常人为的"问题​​",C++书籍不应该花时间解释它的预防措施.`(x = 5)= z`没有将`5`设置为`z`. (20认同)
  • 关于赋值,首先要理解的是它不是关联的.我见过的每本命令式编程教科书都在第1章或第2章中解释了.关于错误输入`(x = y)== z`的评论更有意义. (3认同)
  • 虽然这种行为听起来违反直觉,但这不是一个"问题",因为它是程序员故意做的事情(这就是他们使用括号的原因) (2认同)

Fre*_*Foo 21

没有必要避免这种情况,除非本书针对的是通常(x=y)=z在他们的意思上写作的程序员x=y=z.在实践中,没有人在正确的思想中写道,因此预防措施是完全没必要的.它还禁止其他一些简洁的构造,例如(x=y).nonConstMember(),几乎没有人写,但在某些情况下这可能很有用(尽管它们不应该被过度使用).

@ybungalobill是对的,得到一本更好的书.

  • +1.一个程序员"意外地"编写`(x = y)= z`似乎很可能(并且必要时要防范)程序员意外地编写`x = y + system("rm -rf /")` `X = y`. (9认同)

Pup*_*ppy 13

据我所知,赋值运算符不会在惯用的C++中返回const引用.标准类型也不返回const引用.

std::string a, b, c;
(a = b).clear(); // no objection from compiler
Run Code Online (Sandbox Code Playgroud)

我的所有自定义赋值运算符都返回了非const引用.

如有疑问,请检查标准库.它并非完美无缺,但绝对可以获得这样的基本功能.