2012-12-10 37 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,则它将被称为 。 (我不能想到这个 不会被运营商超载滥用,但语言 当然允许它。)