Problem with results of overloading << for polymorphic types...

P

pmatos

Hi all,

I'm having a problem and for illustration purposes I developed code
that shows what the problem is about. However, any comment on the code
which is not directly about this issue is surely welcome. I have 3
classes, A is abstract, B and C inherit from A and then I create a
vector with B's and C's and print them. Of course, I overload << for
each one of them.
So it is as follows:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class A {
public:
A(string n) : name(n) {}
virtual ~A() {}

virtual string getName() = 0;

protected:
string name;

private:
friend
ostream& operator<<(ostream& s, A& val) {
return s << "<UNPRINTABLE_A>";
}
};

class B : public A {
public:
B(string n) : A(n) {}
virtual ~B() {}

virtual string getName();

private:
friend
ostream& operator<<(ostream& s, B& val) {
return s << "Class B: " << val.getName();
}

};

string B::getName() {
string s = "My name is " + name + ".";
return s;
}

class C : public A {
public:
C(string n) : A(n) {}
virtual ~C() {}

virtual string getName();

private:
friend
ostream& operator<<(ostream& s, C& val) {
return s << "Class C : " << val.getName();
}
};

string C::getName() {
string s = name + "is my name.";
return s;
}

int main() {

vector<A*> v;
v.push_back(new B("b1"));
v.push_back(new B("b2"));
v.push_back(new C("c1"));
v.push_back(new B("b3"));

for(vector<A*>::iterator i = v.begin(); i != v.end(); i++)
cout << **i << endl;

return 0;

}

When I run the program I get:
$ ./testop
<UNPRINTABLE_A>
<UNPRINTABLE_A>
<UNPRINTABLE_A>
<UNPRINTABLE_A>

This is surely not what I expected. How can I have the << for B and C
called?
It's idiot to even have <UNPRINTABLE_A> printed. It should never be
printed. Initially I didn't even though that I needed to overload <<
for A but I do because **i is an A and I do not know if it is a B or a
C. It's logic but at the same time confusing!

Cheers,

Paulo Matos
 
V

Victor Bazarov

pmatos said:
I'm having a problem and for illustration purposes I developed code
that shows what the problem is about. However, any comment on the code
which is not directly about this issue is surely welcome. I have 3
classes, A is abstract, B and C inherit from A and then I create a
vector with B's and C's and print them. Of course, I overload << for
each one of them.
So it is as follows:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class A {
public:
A(string n) : name(n) {}
virtual ~A() {}

virtual string getName() = 0;

protected:
string name;

private:
friend
ostream& operator<<(ostream& s, A& val) {
return s << "<UNPRINTABLE_A>";

Do

return val.print(s);

Add

ostream& print(ostream&) = 0;
};

class B : public A {
public:
B(string n) : A(n) {}
virtual ~B() {}

virtual string getName();

private:
friend
ostream& operator<<(ostream& s, B& val) {
return s << "Class B: " << val.getName();
}

Drop that and implement the 'print' member function instead.

V
 
J

Jerry Coffin

pmatos said:
Hi all,

I'm having a problem and for illustration purposes I developed code
that shows what the problem is about. However, any comment on the
code which is not directly about this issue is surely welcome. I
have 3 classes, A is abstract, B and C inherit from A and then I
create a vector with B's and C's and print them. Of course, I
overload << for each one of them.

Create a (possibly pure) virtual function in the base class to print it
self out. Create an operator<< that calls that virtual function to do
the job. Override the virtual function in the derived classes as
needed. Make sure your operator<< receives the object by const
reference so polymorphism will work.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,832
Latest member
GlennSmall

Latest Threads

Top