2012-01-16 30 views
2

我有一個重載< <操作從我作爲實現Reckful的類如下:其中<<是我在本聲明中的重載操作符?

ostream& operator << (ostream& os, const reckful& p) 
{ 
    os << p.PrintStuff(); 

    return os; 
} 

PrintStuff()只是被Reckful的返回一個字符串的成員函數。

我明白的事情,如果我是寫在main()類似cout << reckobject << endl;方式,cout << reckobject將採取優先和我的重載< <(使用COUT作爲左操作數和reckobject作爲右操作數)將返回的ostream對象os,保留表達式os << endl;以便輸出字符串並結束該行。所以,第一個< <是我宣佈的一個,第二個是標準< <對不對?

然而,我的主要問題是...是什麼事件,這是左右操作數的順序,以及< <運營商,當我運行這樣的語句:

cout << "reckful object = " << reckobject << "!" << endl; 

爲什麼如果在一個< <的兩側沒有ostream對象和垃圾對象時,它可以工作?

謝謝。

回答

5

如果您注意到實施<<的標準方法,它將返回ostream本身。這是關鍵部分

因此,像

cout << "reckful object = " << reckobject << "!" << endl; 

將是

cout << "reckful object = " 

一度被稱爲調用該函數將返回一個ostream與第二通話將被製成

cout << reckobject; 

等等。

你可以測試出你實現你<<作爲

void operator << (ostream& os, const reckful& p) 
{ 
    os << 1; 
} 

在這種情況下,你可以做

std::cout << p; 

但不

std::cout << p << std::endl; 

運營商使其更難了解但考慮這個Point

struct Point 
{ 
    Point& setX(int x) { X = x; return *this;} 
    Point& setY(int y) { Y = y; return *this;} 

    int X; 
    int Y; 
}; 

setXsetY被定義的方式,允許

Point p; 
    p.setX(2).setY(4); 

這是相同的機構<<使用以鏈函數調用。

3

因爲每個<<都返回對cout的引用。由於運營商<<是向左結合,將呼叫從左至右完成,所以

a << b << c 

相當於

(a << b) << c 

這相當於到

operator<<(operator<<(a, b), c); 

所以在你的例子中,你在做

operator<<(operator<<(operator<<(operator<<(cout, "reckful object = "), reckobject), "!"), endl); 

正如你所看到的,每個<<取決於先前<<的返回值(或只是cout的情況下,沒有進一步的左<<)。如果將<<的返回類型之一更改爲void,則可以有效地停止更多<<調用,因爲void不能用作函數的參數。


這不完全等效的,因爲在這個例子中,所有operator<<都是免費的功能,而在現實中,有些可能是成員函數,所以你可以有成員和非成員的混合調用像

operator<<(a, b).operator<<(c); 

operator<<(a.operator<<(b), c);