C ++ - 为什么operator =返回对* this的引用而不是对象* this?

时间:2011-04-12 03:40:56

标签: c++

class MyClass {
  public:
    ...
    MyClass & operator=(const MyClass &rhs); // return MyClass&
    ...
  }

为什么不

class MyClass {
  public:
    ...
    MyClass  operator=(const MyClass &rhs); // return MyClass
    ...
  }

在这种情况下,通过引用返回更有效的原因是什么?

谢谢

// *已更新*

我认为我发现关键原因如下:

int i1, it2, i3;
(i1 = i2) = i3; // i3 will be assigned to i1

如果operator =的返回类型是MyClass而不是MyClass&,则以下语句的执行内容与内部数据类型不同。

MyClass mc1, mc2, mc3;

(mc1 = mc2) = mc3;

遵循内置类型使用的规则,这被视为一种良好的做法。

// *** update ***

#include "stdafx.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    int i1, i2, i3;

    i1 = 0;
    i2 = 2;
    i3 = 3;

    (i1 = i2) = i3;

    cout << "i1: " << i1 << endl;
    cout << "i2: " << i2 << endl;
    cout << "i3: " << i3 << endl;

    return 0;
}

// output from VS2010
/*
i1: 3
i2: 2
i3: 3
*/

3 个答案:

答案 0 :(得分:5)

你的“为什么不”是什么意思?这完全取决于你。如果需要,可以返回对象的副本而不是引用。这没有什么不妥,除了它可能确实效率低下。

在许多情况下,人们更喜欢返回引用,因为它更接近内置赋值运算符的语义。内置运算符返回一个左值,这意味着您可以编写类似

的代码
int a, b = 0;
int *p = &(a = b);
// `p` now points to `a`

不可否认,它不是很有用,但如果你想保留左值语义,你需要从赋值运算符返回一个引用。

<强>更新

您更新的示例不正确。 (i1 = i2) = i3表达式导致未定义的行为,而不是“i3将被分配给i1”,因为您似乎相信。确实,赋值运算符返回左值的事实允许您编译像(i1 = i2) = i3这样的表达式。但是,由于行为未定义,因此该特定表达式无用。

如果是用户定义的分配,就像在(mc1 = mc2) = mc3示例中一样,行为已定义,但仍然远没有用。你为什么要做那样的事?

答案 1 :(得分:1)

只要operator =接收参数为(const T&),它就是一个有效的运算符重载。您可以返回您想要的任何值。 例如,如果我想避免连续的对象复制,我将运算符声明为

void operator = (const T& copy) { }

一旦你尝试x = y = z;编译器就会抛出错误,但x = y;仍然有效! 退货价格根据您的要求而定;如果您愿意,可以返回相同的对象或intchar*,这取决于您。将非const引用返回*this是一种流行的约定。

答案 2 :(得分:0)

我的C ++日子早已不复存在,但你不会用语法创建一个类的临时副本吗?

HTH

马里奥