0

As you can see, only the overloaded version of the stream insertion operator for the base class is called on both instances. I understand why it's so. It's because there is no dynamic binding. But, how do I fix it?

#include <iostream>

using namespace std;

class A {
    int i;
    char c;
public:
    A(int i = 0, char c = ' ') {
        this->i = i;
        this->c = c;
    }
    int getI() { return i; }
    char getC() { return c; }
    friend ostream& operator << (ostream&, A&);
};

class B : public A {
    double d;
public:
    B(int i = 0, char c = ' ', double d = 0.0) : A(i, c), d(d) {}
    friend ostream& operator << (ostream&, B&);
};

ostream& operator << (ostream& out, A& a) {
    out << "\nInteger: " << a.i << "\nCharacter: " << a.c << endl;
    return out;
}

ostream& operator << (ostream& out, B& b) {
    out << "\nInteger: " << b.getI() << "\nCharacter: " << b.getC() << "\nDouble: " << b.d << endl;
    return out;
}

int main() {
    A* a = new A (10, 'x');
    B* b = new B(20, 'y', 5.23);
    A* array[] = { a, b };
    cout << *(array[0]);
    cout << "\n______________________________\n";
    cout << *(array[1]);
    delete a;
    delete b;
    cin.get();
    return 0;
}

How can I make cout << *(array[1]); call the overloaded stream insertion operator that takes an object of B as one of it's arguments?

User2k14
  • 69
  • 5
  • possible duplicate of [Does upcasting make overloading the stream operators (<< && >>) be necessarily overloaded as member functions and not friend functions?](http://stackoverflow.com/questions/29885965/does-upcasting-make-overloading-the-stream-operators-be-necessarily-o) – phantom Apr 27 '15 at 02:51
  • So where's the solution? – User2k14 Apr 27 '15 at 02:52

1 Answers1

1

You can't make it call the overloaded operator, since overloading is resolved at compile time.

To do resolution at runtime, i.e. use dynamic dispatch, you need to move the code that does the printing to a virtual member function.
Then call that from the operator (you only need one, for the base class).

class A
{
  public:
    // ...
    // Override this in B
    virtual void print(std::ostream& o) const
    {
        o << "\nInteger: " << i << "\nCharacter: " << c << endl;
    }
    // ...
};

ostream& operator << (std::ostream& out, const A& a) {
    a.print(out);
    return out;
}
molbdnilo
  • 64,751
  • 3
  • 43
  • 82