C ++ operator =返回* this的引用

时间:2012-08-20 13:23:02

标签: c++ return-type

请查看以下代码:

#include <iostream>
using namespace std;

class Widet{
public:
    Widet(int val = 0):value(val)
    {

    }

    Widet& operator=(Widet &rhs)
    {
        value = rhs.value;
        return *this;
    }
    int getValue()
    {
        return value;
    }
private:
    int value;
};

int main()
{
    Widet obj1(1);
    Widet obj2(2);
    Widet obj3(0);
    (obj3 = obj2) = obj1;
    cout << "obj3 = " << obj3.getValue() << endl;
}

代码成功运行,输出为(使用VS2008):

enter image description here

当我让operator =返回一个值而不是引用时:

Widet operator=(Widet &rhs)
{
    value = rhs.value;
    return *this;
}

它也成功运行,输出为:

enter image description here

我的问题是:为什么第二个代码运行良好?我们不应该收到错误吗?

为什么返回引用* this而不是* this是一个好习惯?

7 个答案:

答案 0 :(得分:8)

  

为什么第二个代码运行良好?我们不应该得到错误吗?

因为它是完全有效的代码。它返回对象的临时副本,并允许您在临时对象上调用成员函数(包括operator=()),因此没有错误。

如果对象不可复制,您将收到错误。

  

为什么返回引用* this而不是* this是一个好习惯?

因为并非所有对象都是可复制的,并且某些对象的复制成本很高。你可以引用任何对象,并且引用总是很便宜。

答案 1 :(得分:3)

通常,您返回一个引用,以便可以使用=运算符作为l值。

答案 2 :(得分:2)

  

为什么第二个代码运行良好?我们不应该得到错误吗?

它运行是因为nonconst成员函数也可以在(nonconst)类rvalues上调用。 operator=的第二个版本返回一个非对象类右值,因此实际上,您将分配给临时值,将前一个值保留在obj3变量中。

因此,没有错误。

答案 3 :(得分:2)

如果您未返回引用,(obj3 = obj2)会提供obj3的临时副本。该副本从obj1获取值并被删除,而obje3永远不会受到第二次分配的影响。

答案 4 :(得分:0)

在第二个示例中,您创建一个临时(Obj3的副本,由operator =返回)并为其分配Obj1。然后它立即被破坏。 Obj3仍然是第一次分配的结果 - Obj3 = Obj2

答案 5 :(得分:0)

从operator =()返回引用可启用以下表达式:

a=b=c;

当您不需要时,返回值可能会过多。它可能导致额外的复制构造函数/析构函数调用。否则,返回一个值是完全有效的C ++。 人们,如果我错了,请纠正我,但我认为由于移动语义,按值返回并不是C ++ 11中的一个大问题。

答案 6 :(得分:0)

(obj3 = obj2)
假设

可以被视为obj3operator=(obj2) // 由于您已将obj2作为参数传递,因此运算符重载会将obj2.value复制到obj3.value。

(obj3 = obj2) = obj1;
operator=返回后,将返回 obj3 (* this,临时副本)。
因此,等效代码将变为obj3=obj1,这将再次调用{{ 1 {}} operator=并将obj3的值重置为obj3.value,即obj1.value