overloading << operators and inherited classes

匿名 (未验证) 提交于 2019-12-03 03:05:02

问题:

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 bar; }  ///////////////////////  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?

回答1:

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.



回答2:

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



回答3:

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

See it in action.



回答4:

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.



文章来源: overloading
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!