赋值操作为什么要返回 reference to *this? 要弄清这个问题之前,先了解函数的返回值类型:返回值类型,返回引用类型
- 返回值类型:返回的是一个对象的副本。
test operator= (const test &t)
{
...
cout << "赋值" << endl;
return *this;
}
当程序中出现test对象之间的赋值操作时, 调用 operator函数。当return *this的时候,会执行拷贝构造test(const test&t),此时的入参为*this(即调用该operator= 函数的对象),返回的对象由*this构造而成。
- 返回引用类型:返回的是对象本身。
test &operator= (const test &t)
{
...
cout << "赋值" << endl;
return *this;
}
和上面一样,当程序中出现test对象之间的赋值操作时,会执行operator=操作,当return *this的时候,返回的是调用该赋值操作对象的本身。
effective C++中说,是为了实现连锁赋值如a = b =c;下面下一个例子,测试一下,如果不返回引用,就不能实现连锁赋值了吗?
class test
{
public:
test() :i(10)
{
cout << "构造" << endl;
}
~test()
{
}
test(const test &t)
{
this->i = t.i;
cout << "拷贝" << endl;
}
test operator= (const test &t)
{
i = t.i;
cout << "赋值" << endl;
return *this;
}
void setData(int value)
{
i = value;
}
int getData()
{
return i;
}
private:
int i;
};
int _tmain(int argc, _TCHAR* argv[])
{
test a;
test b;
test c;
cout << a.getData() << endl << b.getData() << endl<<c.getData() << endl;
a.setData(20);
c = b= a;
cout << a.getData() << endl << b.getData() << endl << c.getData() << endl;
return 0;
}
结果:,可以看出仅仅是在每次赋值完后多了一次拷贝。现在考虑一个情况
如果是(c=b)=a;这种方式呢?
结果:。分析:因为c=b,返回的是一个临时的对象,因此其实最后a赋值给了一个临时变量且多了一次拷贝。
如果换成reference to *this,test& operator= (const test &t) ,查看结果
(c=b)=a,对象c被成功赋值,且整个过程少了两次拷贝。
有的童鞋可能要问,为什么返回this,不是其他。首先明确一点,this是对象的指针。a=b,调用的是对象a的赋值构造函数,赋值结束后,肯定要返回对象a。例如int a = 1; 赋值结束后,肯定返回的是a。
总结:赋值构造函数为了实现赋值操作完成后,可以作为左值接受其他对象的赋值。因此必须返回一个reference to *this,如果返回位值类型,且如果作为左值,则其其对象得不到想要的赋值结果,因为作为左值的是值类型的临时对象。返回引用reference to *this时,赋值操作作为左值,可得到正确的赋值结果。