为什么重载赋值运算符要返回类的引用?

5
class item {
public:
    item& operator=(const item &rh) {
        ...
        ...
        return *this;
    }
};

以下签名是否错误?
void operator=(const item &rh);

item a, b;
a = b; // equivalent to a.operator=(b); so there is no need to return this.
3个回答

10

它并不是“错误”的,但令人惊讶。赋值运算符的结果是目标对象。这就是内置含义。如果您为自己的类定义了不同的含义,可能会使人们感到困惑。

例如:

int c;
while((c = getchar()) != EOF) {
  // ...
}

对于c的赋值返回了c本身,并在此之后将其与EOF进行比较。用户希望你的item类表现出相似的行为。


6
签名为void的函数不允许链接赋值:
a = b = c;
< p >(查看Johannes的答案,了解基于赋值返回已分配值的用法模式的另一个示例。) < p >这就是为什么不鼓励使用这样的签名。但是,如果我没有错的话,您实际上是可以使用这样的签名的。

关键是这就是内置类型所做的。 - jk.

2

这是完全合法的。但是当您像那样声明operator=时,您将无法进行"连续赋值链":

item a(X);
item b;
item c;
c = b = a;

引用允许修改返回值。由于operator=从右到左进行评估,所以我向您展示的用法是有效的。

编辑 此外,正如其他人提到的那样,返回值经常用于表达式,例如while (a = cin.get()) != 'q')。但是,您也可以声明类似A operator=(const A&)(返回副本)或const A& operator(const A&)(返回const引用)的运算符。我的观点是:此运算符可以返回任何东西,但惯用的方式是返回非const引用到自身。


1
不仅如此,将operator=声明为返回void,您将无法将赋值的结果用于任何表达式。 - Matteo Italia

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