简体   繁体   English

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

[英]C++ operator= return reference to *this

Look at the following code: 看下面的代码:

#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;
}

The code runs successfully and the output is (using VS2008): 代码运行成功,输出为(使用VS2008):

在此输入图像描述

When I let the operator= return a value instead of reference: 当我让operator =返回一个值而不是引用时:

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

It also runs successfully and the output is : 它也成功运行,输出为:

在此输入图像描述

My question is :Why the second code runs well?Should not we get a error? 我的问题是:为什么第二个代码运行良好?我们不应该得到错误吗?

Why it is a good habit to return reference to *this instead of *this? 为什么返回引用* this而不是* this这是一个好习惯?

Why the second code runs well?Should not we get a error? 为什么第二个代码运行良好?我们不应该得到错误吗?

Because it's perfectly valid code. 因为它是完全有效的代码。 It returns a temporary copy of the object, and you're allowed to call member functions (including operator=() ) on temporary objects, so there is no error. 它返回对象的临时副本,并允许您对临时对象调用成员函数(包括operator=() ),因此没有错误。

You would get an error if the object were uncopyable. 如果对象不可复制,您将收到错误。

Why it is a good habit to return reference to *this instead of *this? 为什么返回引用* this而不是* this这是一个好习惯?

Because not all objects are copyable, and some objects are expensive to copy. 因为并非所有对象都是可复制的,并且某些对象的复制成本很高。 You can take a reference to any object, and references are always cheap to pass around. 您可以引用任何对象,并且引用总是很便宜。

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

Why the second code runs well?Should not we get a error? 为什么第二个代码运行良好?我们不应该得到错误吗?

It runs because nonconst member functions can be called on (nonconst) class rvalues as well. 它运行是因为nonconst成员函数也可以在(nonconst)类rvalues上调用。 The second version of operator= returns a nonconst class rvalue, so in effect, you assign to the temporary, leaving the previous value in the obj3 variable. operator=的第二个版本返回一个nonconst类rvalue,因此实际上,您将分配给临时值,将前一个值保留在obj3变量中。

Therefore, there is no error. 因此,没有错误。

When you don't return a reference, (obj3 = obj2) gives a temporary copy of obj3 . 当你不回一个参考, (obj3 = obj2)给出的临时副本obj3 The copy obtains the value from obj1 and is deleted, while obje3 is never affected by the second assignment. 副本从obj1获取值并被删除,而obje3从不受第二个赋值的影响。

In the second example you create a temporary (a copy of Obj3, returned by operator=) and assign Obj1 to it. 在第二个示例中,您创建一个临时(Obj3的副本,由operator =返回)并为其分配Obj1。 Then it immediately gets destructed. 然后它立即被破坏。 Obj3 remains the result of first assignment - Obj3 = Obj2 . Obj3仍然是第一次分配的结果 - Obj3 = Obj2

Returning a reference from operator=() enables expressions like: 从operator =()返回引用可启用以下表达式:

a=b=c;

Returning a value may be excessive when you don't need it. 当您不需要时,返回值可能会过多。 It can cause extra copy-constructor/destructor calls. 它可能导致额外的复制构造函数/析构函数调用。 Otherwise, returning a value is perfectly valid C++. 否则,返回一个值是完全有效的C ++。 People, please correct me if I'm wrong, but I think returning by value is not that big of an issue in C++11 because of move semantics. 人们,如果我错了,请纠正我,但我认为由于移动语义,按值返回并不是C ++ 11中的大问题。

(obj3 = obj2)

can be considered as obj3operator=(obj2) //hypothetically. 可以假设为obj3operator=(obj2) //。
Since you have passed obj2 as parameter, your operator overload will copy the obj2.value into obj3.value. 由于您已将obj2作为参数传递,因此运算符重载会将obj2.value复制到obj3.value中。

(obj3 = obj2) = obj1;
After the return of from operator= , obj3 (*this,temporary copy) will be returned. operator=返回后,将返回obj3 (* this,temporary copy)。
So the equivalent code becomes obj3=obj1 which will again invoke operator= of obj3 and will reset value of obj3.value to obj1.value ie 1 . 这样的等效代码变得obj3=obj1这将再次调用operator=obj3且复位的值obj3.valueobj1.value1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM