2011-08-24 51 views
4

当你为一个类重载一个类的< <运算符(假设它被定义为SomeClass中的一个朋友)时,为什么你都引用ostream并返回该ostream?Ostream << overloading confusion

ostream& operator<<(ostream& s, const SomeClass& c) { 
    //whatever 
    return s; 
} 

什么好处可以返回ostream时,它已经可以直接修改引用?这似乎是多余的,我 - 尽管我敢肯定它不是:)

回答

4

这不是多余的,但对于链接调用非常有用。它很容易看到类似的std :: string ::附加功能,所以我会与开始:

std::string mystring("first"); 
mystring.append(" second"); 
mystring.append(" third"); 

可以改写为:

std::string mystring("first").append(" second").append(" third"); 

这是可能的,因为.append()返回对它修改的字符串的引用,所以我们可以继续添加.append(...)到最后。与您正在做什么相关的代码正在改变:

std::cout << "first"; 
std::cout << " second"; 
std::cout << " third"; 

进入此。由于运营商< <返回流,我们也可以链接这些!

std::cout << "first" << " second" << " third"; 

看到相似性和有用性?

+0

谢谢 - 每个人都有类似的答案,但我赞赏这个例子 - 它使得它更加明显。 :) –

4

所以,你可以写的operator<<链接,调用为:

stream << s1 << s2 << s3 ; 

如果你不回ostream&,那么你就不能写它不止一次。

你能想到的,无论是作为:

operator<<(operator<<(operator<<(stream, s1), s2), s3); 

或者像,

((stream << s1) << s2) << s3 ; 

首先(stream << s1)回报stream&上,您再次调用<<,并且变得stream << s2这对您再次返回stream&调用<<并且它变成stream << s3

5

它允许一起“链”输出。如:

std::cout << someObj << someValue; 

这相当于是这样的:

operator<<(operator<<(std::cout, someObj), someValue); 
1

啊,这是如此连接的输出,象

COUT < < “这” < < “为” < < “笔” < < ENDL;

仍然有效。