Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global operators and polymorphism

I have two classes, with two global friend oparator<<s.

class A {
    friend std::ostream& operator<<(std::ostream& o, const A &a);
};

class B: public A {
    friend std::ostream& operator<<(std::ostream& o, const B &b);
};

If i use it like this, everything is working fine, the B version of the operator gets called:

B b;
std::cout << b;

But if i use polymorpism, the A version gets called, although the dynamic type is B:

A* b = new B();
std::cout << *b;

One solution is casting:

std::cout << static_cast<B&>(*b);

but is there any simpler or more elegant solution for this?

like image 311
WonderCsabo Avatar asked Apr 03 '13 11:04

WonderCsabo


2 Answers

Yes. One output operator and virtual print function in classes.

class A
{
public:
   virtual ~A() {}
private:
   virtual void print(std::ostream&) {}
   friend std::ostream& operator << (std::ostream& os, const A& obj)
   {
      obj.print(os);
      return os;
   }
};

class B
{
private:
   virtual void print(std::ostream&) {}
};

Live example

like image 97
ForEveR Avatar answered Sep 22 '22 06:09

ForEveR


Versions of functions in derived classes are only called when you access them via a pointer to the base class if you define them as virtual because the compiler hasn't a clue what the class of the object pointed to by the pointer actually is.

Here the trouble is that you are defining friend functions so they cannot themselves be virtual, the solution is simple: have the implementation of A's operator<< call a virtual function in A that you can then overload in B.

like image 21
Jack Aidley Avatar answered Sep 22 '22 06:09

Jack Aidley