开发者

overloading << operators and inherited classes

I've got a base class and then several derived classes. I would like to overload the "<<" operator for these derived classes. For normal operators, i.e. '+', virtual functions do the trick. What I understand to be the standard convention is to declare

friend ostream& operator<<(ostream& out, MyClass& A);

within my class and then define the function after the class. A priori I would think adding virtual to the above definition would make it work, but after some thought (and errors from my compiler) I realize that doesn't make much sense.

I tried a different tack on a test case, where all the class members are public. For example:

class Foo{
 //bla
};

ostream& operator<<(ostream& out, Foo& foo){
  cout << "Foo" << endl;
  return foo;
}

class Bar : public Foo{
 //bla
};

ostream& operator<<(ostream& out, Bar& bar){
  cout << "Bar" << endl;
  return b开发者_如何转开发ar;
}

///////////////////////

Bar bar = Bar();
cout << bar << endl; // outputs 'Foo', not 'Bar' 

So in some way this is "polymorphism gone bad" -- the base class operator<< is being called rather than the derived class operator. In the above example, how do I make the correct operator get called for the derived class? And more generally, if my class has private members I want to protect, how can I correct the operator overloading while using the friend keyword?


You can use a virtual helper function. Here's a completely untested example, so excuse any syntax mistakes:

virtual ostream& Foo::print(ostream& out) const {
    return out << "Foo";
}

virtual ostream& Bar::print(ostream& out) const {
    return out << "Bar";
}

// If print is public, this doesn't need to be a friend.
ostream& operator<<(ostream& out, const Foo& foo) {
    return foo.print(out);
}

Edit: Cleaned up per @Omnifarious suggestions.


Usually you just create a polymorphic print method in the base class which is called by a single free friend function.


Make operator<< a free function that forwards the call to a virtual method of class Foo.

See it in action.


With the proper code corrections in place, your code works fine; nothing to be done:

ostream& operator<<(ostream& out, Foo& foo) {
  out << "Foo" << endl;  // 'out' and not 'cout'
  return out;  // returns 'out' and not 'foo'
}

ostream& operator<<(ostream& out, Bar& bar) {
  out << "Bar" << endl;  // 'out' and not 'cout'
  return out;  // returns 'out' and not 'bar'
}

Demo. For accessing private members, you can make this function as friend in the desired class.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜