4

I thought that in

cout << "Hello world" 

cout object has an operator overloading so we can pass strings into cout objects member function.

But in some example code I saw a class which has an operator overloading defined in it.

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

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

Even if it is not, what if both cout and aGenericPlayer overload operator<< ?

Mooing Duck
  • 56,371
  • 16
  • 89
  • 146

4 Answers4

8

Even if it is not, what if both cout and aGenericPlayer overload operator<< ?

std::cout is an std::ostream object, so any std::ostream& operator<<(std::ostream, SomeType) will work with std::cout. But the point is that the second parameter of the operator is different, so the overloads are different. The first "string" one is something like

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

and the second

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

So, they are different operator overloads and there is no ambiguity.

juanchopanza
  • 210,243
  • 27
  • 363
  • 452
2

First, neither cout nor aGenericPlayer can overload anything. They're objects, and overloading is based on types (even if you wouldn't normally says that type X overloads <<, but rather that there is an overload of << which can take a type X as its second argument).

Second, overload resolution is based on all of the arguments, not just one. There are something around twenty different overloads of << for std::istream (which is a base class of the type of std::cout), but none (at least in the standard library) take a GenericPlayer as second parameter. So they can't be used if the second operand isn't a GenericPlayer. Similarly, you could have an operator<<( int, GenericPlayer const& ), in addition to the one you have; it would be called if the left hand side had type int, and the right hand side type GenericPlayer. (I can't think of any case where this wouldn't be operator overloading abuse, but the language certainly allows it.)

James Kanze
  • 142,482
  • 15
  • 169
  • 310
1

In order for cout to accept a GenericPlayer object, you have to overload operator<<. operator<< is also called the insertion operator. So if you take that in context, you are inserting the output of your custom function to cout. The overloaded operator returns a reference to the original ostream object, which also means you can combine insertions. You must overload the insertion operator to recognize an ostream object on the left and a GenericPlayer on the right. See also Overloading the << Operator for Your Own Classes . As far as cout goes, cout is an object of class ostream that represents the standard output stream. It corresponds to the cstdio stream stdout. Because cout is an object of class ostream, we can write characters to it either as formatted data using for example the insertion operator (ostream::operator<<) or as unformatted data using the write member function, among others

  • I actually agree with your basic idea, that the `< – James Kanze Dec 10 '12 at 22:00
  • @JamesKanze: When applied to an ostream operator, I believe the convention is `insertion`. –  Dec 10 '12 at 22:07
  • 1
    Agreed. And for most applications, that's the _only_ use; most programmers probably think of insertion as the operator's primary meaning (although historically, it was the left shift operator first). – James Kanze Dec 11 '12 at 10:21
  • @JamesKanze: You might be interested in this SO question: http://stackoverflow.com/questions/4854248/why-are-bitwise-shifts-and-used-for-cout-and-cin –  Dec 11 '12 at 13:42
1

what if both cout and aGenericPlayer overload operator<<

Neither of them overload it, it is overloaded as a regular function (not a member). Note the use of friend in your example; this allows the function to access the class's internals without being a member. Therefore, this situation is avoided.

Dan
  • 10,532
  • 2
  • 42
  • 74