By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,194 Members | 841 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,194 IT Pros & Developers. It's quick & easy.

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

P: n/a
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

Jul 23 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
"pmatos" <po**@sat.inesc-id.pt> wrote...
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
Jul 23 '05 #2

P: n/a
pmatos wrote:
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.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 23 '05 #3

P: n/a
"Victor Bazarov" <v.********@comAcast.net> wrote...
"pmatos" <po**@sat.inesc-id.pt> wrote...
[..]
Do

return val.print(s);
}
Add

ostream& print(ostream&) = 0;


Did I miss the 'virtual' keyword here? Damn! Should be

virtual ostream& print(ostream&) = 0;
[..]

Jul 23 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.