2011-04-12 35 views
0
class MyClass { 
    public: 
    ... 
    MyClass & operator=(const MyClass &rhs); // return MyClass& 
    ... 
    } 

为什么不C++ - 为什么operator =返回* this的引用而不是* this的对象?

class MyClass { 
    public: 
    ... 
    MyClass operator=(const MyClass &rhs); // return MyClass 
    ... 
    } 

难道它是更有效的参考在这种情况下,返回的原因是什么?

谢谢

// *更新*

我想我找到了关键的原因如下:

int i1, it2, i3; 
(i1 = i2) = i3; // i3 will be assigned to i1 

如果操作的返回类型=是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

见本类似的问题:(http://stackoverflow.com/q/2447696/478288) – chrisaycock 2011-04-12 03:47:21

+0

否,'i3'将不会分配[在C++重载赋值运算符] 'i1'。其实这个行为在你的'(i1 = i2)= i3'赋值中是未定义的。 – AnT 2011-04-12 04:34:59

+0

@AndreyT:请参阅我的update2。 – q0987 2011-04-12 18:03:21

回答

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

只要operator =收到参数(const T&),它就是一个有效的运算符重载。你可以返回你想要的任何值。 例如,如果我想避免连续对象拷贝,我只要你尝试x = y = z;编译器会抛出错误申报操作员,

void operator = (const T& copy) { } 

,但x = y;仍然是有效的!返回值基于您的要求;如果你想要,你可以返回相同的对象或intchar*,这取决于你。将非const引用返回给*this是流行的约定。

+0

作为常量引用的参数甚至不是必需的......参数不一定是'const&',它可以是非const引用,或者甚至是按值传递。事实上,你可以定义你自己的'operator ='来取任何类型(好吧,如果你没有声明'',那么编译器会隐式定义'T&operator =(T const&)'?运算符=(T)',''运算符(T&)'或'运算符=(T const&)'是''''是你决定返回的任何内容 – 2011-04-12 07:58:13

+0

Second @David Rodriguez - 这是不正确的说法,该参数应该是一个const引用。实际上到目前为止,重载=运算符的最佳方式是需要参数值传递的copy和swap机制。/questions/3279543/what-the-copy-and-swap-idiom)并更正你的答案。 – 2011-04-12 08:51:31

0

我的C++时代早已逝去,但是您不会在语法中创建类的临时副本吗?

HTH

马里奥

相关问题