2012-12-10 39 views
4

我認爲在在C++中會發生什麼,如果兩個對象都重載operator <<?一個<< b

cout << "Hello world" 

cout對象具有一個運算符重載,以便我們可以通過stringscout對象的成員函數。

但在一些示例代碼中,我看到一個類中定義了一個運算符重載。

class GenericPlayer : public Hand 
{ 
    .. 
    friend ostream& operator <<(ostream& os, const GenericPlayer& aGenericPlayer); 
    .. 
}; 

... 
cout << aGenericPlayer << endl; 
... 

即使不是這樣,如果什麼都coutaGenericPlayer超載operator<<

+2

您是否問'cout'和'GenericPlayer'是否定義了一個插入運算符(' << GenericPlayer'')? – GManNickG

+3

如果'operator <<'的多個定義與給定的操作數匹配,則根據C++ 03§13.3'[over.match]'中闡述的複雜的重載解析規則選擇「最佳」匹配。如果「最佳」匹配不是唯一的或不存在,那麼這是一個錯誤。 –

回答

8

即使不是,如果cout和aGenericPlayer都重載運算符< <怎麼辦?

std::coutstd::ostream對象,所以任何std::ostream& operator<<(std::ostream, SomeType)將與std::cout工作。但重點是運營商的第二個參數是不同的,所以過載是不同的。第一個「串」,一個是像

std::ostream& operator<<(std::ostream&, const char*); 

和第二

std::ostream& operator <<(std::ostream& os, const GenericPlayer& aGenericPlayer); 

因此,它們是不同的運算符重載,沒有歧義。

+0

我想你的意思是「所以一個運算符<<(std :: ostream&,something_else)將與cout一起工作」? –

+0

@ReubenMorais是的,這正是我的意思。編輯。 – juanchopanza

1

爲了使cout接受GenericPlayer對象,您必須重載operator<<operator<<也被稱爲插入運算符。所以如果你在上下文中使用它,你可以將自定義函數的輸出插入到cout。重載操作符返回對原始ostream對象的引用,這也意味着您可以組合插入。您必須使插入操作符超載才能識別左側的ostream對象和右側的GenericPlayer。另見Overloading the << Operator for Your Own Classes。就cout而言,cout是代表標準輸出流的class ostream的對象。它對應於cstdiostdout。因爲cout是類的ostream的目的,我們可以寫出使用寫入成員函數使用例如插入運算符字符它無論是作爲格式化數據(ostream的::運算< <)或作爲無格式數據等

+0

我其實同意你的基本思想,即<< <<操作符是插入操作符。但是這個術語適用於像BigInteger運算符<<(BigInteger const&lhs,int rhs)'的情況。在人類讀者層面,操作符'<<'也被超載:插入或左移。 –

+0

@JamesKanze:當應用於一個ostream運算符時,我認爲該約定是'insertion'。 – 2012-12-10 22:07:45

+1

同意。對於大多數應用程序來說,這僅僅是用途;大多數程序員可能會認爲插入是操作符的主要含義(儘管歷史上它是第一個左移操作符)。 –

1

如果什麼都cout和aGenericPlayer超負荷運營商< <

兩人都不超載,它是重載作爲常規功能(不是成員)。請注意在你的例子中使用friend;這允許函數在不成爲成員的情況下訪問類的內部。因此,這種情況是可以避免的。

2

首先,既不是cout也不是aGenericPlayer可以超載 什麼。它們是對象,過載基於類型 (即使您通常不會說類型X過載<<, ,而是存在<<的過載,該過載可能會將 類型X作爲其第二個參數)。

其次,重載決議是基於所有參數,而不僅僅是一個。有大約二十種不同的 過載<<std::istream(它是基類 的類型std::cout),但沒有(至少在標準 庫)採取GenericPlayer作爲第二個參數。因此,如果第二個操作數不是GenericPlayer,則不能使用它們 。 同樣,除了你所擁有的一個,你還可以有一個operator<<(int, GenericPlayer const&);如果左手邊的類型爲int,右手邊的 類型爲GenericPlayer,則它將被稱爲 。 (我不能想到這個 不會被運營商超載濫用,但語言 當然允許它。)