Reputation: 69
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?
Upvotes: 0
Views: 164
Reputation: 23058
You can define virtual member helper functions.
class A {
public:
virtual void toStream(ostream& out) const {
out << "\nInteger: " << i << "\nCharacter: " << c << endl;
}
};
class B : public A {
public:
virtual void toStream(ostream& out) const {
out << "\nInteger: " << getI() << "\nCharacter: " << getC() << "\nDouble: " << d << endl;
}
};
ostream& operator << (ostream& out, const A& a) {
a.toStream(out);
return out;
}
You don't even need 2 operator<<()
's anymore.
For operator >> (istream& in, A& a)
, similar tricks could be done.
class A {
public:
virtual void fromStream(istream& in) {
// Fill data members with in
}
};
class B : public A {
public:
virtual void fromStream(istream& in) {
// Fill data members with in
}
};
istream& operator >> (istream& in, A& a) {
a.fromStream(in);
return in;
}
Upvotes: 2
Reputation: 1054
If A
knows it will be inherited from, you can use Non Virtual Interface: make the operators friend, and write a protected (it's not part of the class interface) virtual function that performs the write.
Upvotes: 0