4

我以为在

cout << "Hello world" 

cout对象有一个运算符重载,因此我们可以传递stringscout对象的成员函数。

但是在一些示例代码中,我看到一个类中定义了一个运算符重载。

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

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

即使不是,如果两者都cout超载aGenericPlayer怎么operator<<办?


即使不是,如果 cout 和 aGenericPlayer 都重载 operator<< 怎么办?

std::cout是一个std::ostream对象,所以 anystd::ostream& operator<<(std::ostream, SomeType)都可以使用std::cout. 但重点是操作符的第二个参数不同,所以重载也不一样。第一个“字符串”类似于

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

第二个

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

因此,它们是不同的运算符重载,没有歧义。

4

4 回答 4

8

即使不是,如果 cout 和 aGenericPlayer 都重载 operator<< 怎么办?

std::cout是一个std::ostream对象,所以 anystd::ostream& operator<<(std::ostream, SomeType)都可以使用std::cout. 但重点是操作符的第二个参数不同,所以重载也不一样。第一个“字符串”类似于

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

第二个

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

因此,它们是不同的运算符重载,没有歧义。

于 2012-12-10T21:44:54.000 回答
2

首先,既cout不能也aGenericPlayer不能超载任何东西。它们是对象,重载基于类型(即使您通常不会说类型 X 重载<<,而是说有一个重载<<可以将类型 X 作为其第二个参数)。

其次,重载决议基于所有参数,而不仅仅是一个。<<for有大约 20 种不同的重载std::istream(它是 of 类型的基类std::cout),但没有一个(至少在标准库中)将 aGenericPlayer作为第二个参数。因此,如果第二个操作数不是 a ,则不能使用它们GenericPlayer。同样,operator<<( int, GenericPlayer const& )除了您拥有的 , 您还可以拥有一个;如果左边有类型int,右边有类型,就会被调用GenericPlayer。(我想不出这不会是运算符重载滥用的任何情况,但语言肯定允许这样做。)

于 2012-12-10T21:57:49.837 回答
1

为了cout接受一个GenericPlayer对象,你必须重载operator<<operator<<也称为插入运算符。因此,如果您将其放在上下文中,您将自定义函数的输出插入到cout. 重载的运算符返回对原始 ostream 对象的引用,这也意味着您可以组合插入。您必须重载插入运算符才能识别ostream左侧的对象和GenericPlayer右侧的 a。另请参阅为您自己的类重载 << 运算符 。就目前cout而言,cout是一个class ostream代表标准输出流的对象。它对应于cstdiostdout。因为cout是类 ostream 的对象,我们可以使用例如插入运算符 (ostream::operator<<) 将字符作为格式化数据写入它,或者使用 write 成员函数作为未格式化数据写入它

于 2012-12-10T21:45:00.827 回答
1

如果 cout 和 aGenericPlayer 都重载 operator<<

它们都没有重载它,它作为常规函数(不是成员)被重载。请注意friend您的示例中的使用;这允许函数在不成为成员的情况下访问类的内部。因此,可以避免这种情况。

于 2012-12-10T21:51:35.727 回答