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
*/
答案 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;
仍然有效!
退货价格根据您的要求而定;如果您愿意,可以返回相同的对象或int
或char*
,这取决于您。将非const引用返回*this
是一种流行的约定。
答案 2 :(得分:0)
我的C ++日子早已不复存在,但你不会用语法创建一个类的临时副本吗?
HTH
马里奥