[英]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.value
到obj1.value
即1
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.