【问题标题】:In c++ what happens, if both objects overload operator<<? a<<b在 C++ 中,如果两个对象都重载 operator<<?一个<<b
【发布时间】:2012-11-28 09:15:18
【问题描述】:

我认为在

cout << "Hello world" 

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

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

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

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

即使不是,如果coutaGenericPlayer都超载operator&lt;&lt;怎么办?

【问题讨论】:

  • 您是在问coutGenericPlayer 是否都为GenericPlayer 定义了插入运算符(&lt;&lt;)?
  • 如果operator&lt;&lt; 的多个定义与给定的操作数匹配,则根据C++03 §13.3 [over.match] 中规定的复杂重载决议规则选择“最佳”匹配。如果“最佳”匹配不是唯一的或不存在,则为错误。

标签: c++ operator-overloading


【解决方案1】:

即使不是,如果 cout 和 aGenericPlayer 都重载操作符怎么办

std::cout 是一个std::ostream 对象,因此任何std::ostream&amp; operator&lt;&lt;(std::ostream, SomeType) 都可以与std::cout 一起使用。但重点是操作符的第二个参数不同,所以重载也不一样。第一个“字符串”类似于

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

第二个

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

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

【讨论】:

  • 我想你的意思是“所以运算符
  • @ReubenMorais 是的,这正是我的意思。已编辑。
【解决方案2】:

首先,coutaGenericPlayer 都不能超载 任何事物。它们是对象,重载基于类型 (即使你通常不会说 X 型重载 &lt;&lt;, 而是&lt;&lt; 的过载可能需要 输入 X 作为它的第二个参数)。

其次,重载决议基于所有参数, 不只是一个。大约有二十种不同的东西 &lt;&lt;std::istream 的重载(它是 std::cout 的类型),但没有(至少在标准中 library) 将GenericPlayer 作为第二个参数。所以他们 如果第二个操作数不是GenericPlayer,则不能使用。 同样,除了您拥有的operator<<( int, GenericPlayer const& ),您还可以拥有一个operator<<( int, GenericPlayer const& );它会被称为 如果左侧有类型int,而右侧 输入GenericPlayer。 (我想不出任何这种情况 不会是运算符重载滥用,而是语言 当然允许。)

【讨论】:

    【解决方案3】:

    为了让cout 接受GenericPlayer 对象,您必须重载operator&lt;&lt;operator&lt;&lt; 也称为 insertion 运算符。因此,如果您将其放在上下文中,您会将自定义函数的输出插入到cout。重载运算符返回对原始 ostream 对象的引用,这也意味着您可以组合插入。您必须重载插入运算符才能识别左侧的ostream 对象和右侧的GenericPlayer。另见Overloading the << Operator for Your Own Classes 。就cout 而言,cout 是代表标准输出流的class ostream 的对象。它对应于cstdiostdout。因为cout 是 ostream 类的对象,所以我们可以使用插入运算符 (ostream::operator

    【讨论】:

    • 我实际上同意你的基本想法,&lt;&lt; 运算符是插入运算符。但是这个词在BigInteger operator&lt;&lt;( BigInteger const&amp; lhs, int rhs )这样的情况下是否合适。在人类读者层面,运算符&lt;&lt; 也被重载:插入或左移。
    • @JamesKanze:当应用于 ostream 运算符时,我相信约定是insertion
    • 同意。而对于大多数应用程序来说,这是only 的用途;大多数程序员可能认为插入是运算符的主要含义(尽管从历史上看,它首先是左移运算符)。
    • @JamesKanze:您可能对这个 SO 问题感兴趣:stackoverflow.com/questions/4854248/…
    【解决方案4】:

    如果 cout 和 aGenericPlayer 都重载运算符会怎样

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      • 2010-12-14
      • 2021-04-09
      • 1970-01-01
      • 2012-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多