2011-11-19 75 views
1

这是一个赋值运算符。 &rhs != this令人困惑。我的问题:rhs是消息类型的参考。 &rhs是什么意思? &做什么(一个参考的内存地址?)? 另一个问题是关于return *this。因为我们想要一个类型为Message的引用,但是*这是一个Message类型的对象,对吗?我们如何将对象返回给引用?&rhs!= this,比较指针的引用?

Message& Message::operator=(const Message &rhs) 
{ 
    if (&rhs != this) 
    { 
     some functions; 
    } 
    return *this; 
} 
+0

明白为什么这个模式是在几乎所有运营商共同=方法,阅读Scott Meyer的Effective C++;在第3版中,请参阅项目#10和#11(这些可通过亚马逊的“Look Inside”机制阅读)http://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876#reader_0321334876其实,整本书都是推荐阅读。 – franji1

+0

@ franji1:我不会说这很普通。如果你一直交换,那更好,那么你通常不需要对每个呼叫者强制自我分配检查。 –

回答

10

&rhs表示引用参照的对象的地址。

Message a; 
const Message &rhs = a; 

if (&rhs == &a) std::cout << "true" << std::endl; 

这是将打印true

引用不是一个不同的对象;它只是一个指针的语法糖,它指向参考它的同一个对象。所以,当你写return this,它返回一个指向对象,但如果你写return *this,它返回无论是复制对象的,或参考对象,根据不同的返回类型。如果返回类型是Message &,那么您告诉编译器“不作复制,而是返回相同的对象”。现在的相同的对象不过是一个参考。对象的引用可以随时进行。例如,请参阅上面的rhs声明;它是const Message & rhs = a,由于targer类型被称为引用类型,因此您正在对象a的引用rhs。这很简单。

+0

'return * this'呢? '* this'是一个对象。但返回类型是一个消息类型引用'Message&' – ihm

+0

所以基本上,rhs只是a的另一个名称。 – ihm

+1

@姆:是的。它只是另一个名字。这是一个别名。 – Nawaz

2

引用仅仅是一个别名对象。引用是通过调用函数的请求形成的;它们不是(必然)是对象类型的一部分。这可能你已经很熟悉了,但考虑一下:

void f1(int a) { ++a; } 
void f2(int & a { ++a; } 

int main() 
{ 
    int x = 5; 
    f1(x); 
    f2(x); 
} 

当然你知道两个函数之间的区别。但请注意,x始终只是int类型的对象。无论是通过引用还是按价值传递,都不是x的属性,而是该函数的属性。

这同样适用于返回类型:

int q; 
int g1() { return q; } 
int & g2() { return q; } 

int main() 
{ 
    ++g2(); 
    ++g1(); // error 
} 

再次,q只是一个对象。 return q;是按价值还是按参考返还,不是q的财产,而是该功能的属性。 g1复制q,而g2返回对实际的q对象的引用(我们可以增加)。在您的例子(的g1返回值不能增加,恰恰是因为它没有一个永久的存在,这将是毫无意义的(technially,表达的是一个右值)。)

所以,return *this;返回参考到对象本身。这与this无关,但它与所有函数的返回类型为Message&有关。

+0

谢谢SB,它有很大帮助 – ihm

+0

您是否暗示'++ g1()'是一个编译错误*,因为它返回一个右值*?如果是这样,它是不完全正确的。 – Nawaz

+0

@Nawaz:不,表达式*在这一点是一个右值,并且因为它是基本类型,它不能递增,我已经重写了它。 –

4

除了Nawaz的伟大answer,我想指出的是,你必须要小心参考返回到本地变量在函数返回时,将走出去的范围。因此,避免返回这样的参考:

string& foo() 
{ 
    string result = "abc"; 
    return result; 
} 

这将导致以下编译器警告:

参照本地变量result返回