stl containers and polymorphism

  • Thread starter Maurice Termeer
  • Start date
M

Maurice Termeer

Hi, suppose i've got a nice tree of polymorphic types, like an abstract
base class shape and some subclasses like circle, traingle and square.
Now i also happen to have a list of pointers to triangles (so of type
list<triangle *>) and i want to pass this list to a function that
accepts a list of shapes (so the parameter is of type list<shape *>).
How can I cast the triangle list to a list of shapes?

The normal cast operators don't work, then the compiler says something like:

'reinterpret_cast' : cannot convert from 'std::list<_Ty>' to
std::list<_Ty>' with [ _Ty=triangle * ] and [ _Ty=shape * ] Conversion
requires a constructor or user-defined-conversion operator, which can't
be used by const_cast or reinterpret_cast

or

'static_cast' : cannot convert from 'std::list<_Ty>' to 'std::list<_Ty>'
with [ _Ty=triangle * ] and [ _Ty=shape * ] No constructor could
take the source type, or constructor overload resolution was ambiguous

what does this mean, and more important, how do I solve this?

Maurice Termeer
 
B

Bob Hairgrove

Hi, suppose i've got a nice tree of polymorphic types, like an abstract
base class shape and some subclasses like circle, traingle and square.
Now i also happen to have a list of pointers to triangles (so of type
list<triangle *>) and i want to pass this list to a function that
accepts a list of shapes (so the parameter is of type list<shape *>).
How can I cast the triangle list to a list of shapes?

The normal cast operators don't work, then the compiler says something like:

'reinterpret_cast' : cannot convert from 'std::list<_Ty>' to
std::list<_Ty>' with [ _Ty=triangle * ] and [ _Ty=shape * ] Conversion
requires a constructor or user-defined-conversion operator, which can't
be used by const_cast or reinterpret_cast

or

'static_cast' : cannot convert from 'std::list<_Ty>' to 'std::list<_Ty>'
with [ _Ty=triangle * ] and [ _Ty=shape * ] No constructor could
take the source type, or constructor overload resolution was ambiguous

what does this mean, and more important, how do I solve this?

Maurice Termeer

You can copy the list<triangle*> to a new list<shape*> element by
element (i.e. use assign() or std::copy) and pass the list<shape*> to
the function. Or you can keep the triangle pointers in a list<shape*>
to begin with.

But list<shape*> is a different type than list<triangle*>, and they
are not related since there is no inheritance.
 
T

Tom Widmer

Hi, suppose i've got a nice tree of polymorphic types, like an abstract
base class shape and some subclasses like circle, traingle and square.
Now i also happen to have a list of pointers to triangles (so of type
list<triangle *>) and i want to pass this list to a function that
accepts a list of shapes (so the parameter is of type list<shape *>).
How can I cast the triangle list to a list of shapes?

The normal cast operators don't work, then the compiler says something like:

'reinterpret_cast' : cannot convert from 'std::list<_Ty>' to
std::list<_Ty>' with [ _Ty=triangle * ] and [ _Ty=shape * ] Conversion
requires a constructor or user-defined-conversion operator, which can't
be used by const_cast or reinterpret_cast

or

'static_cast' : cannot convert from 'std::list<_Ty>' to 'std::list<_Ty>'
with [ _Ty=triangle * ] and [ _Ty=shape * ] No constructor could
take the source type, or constructor overload resolution was ambiguous

what does this mean, and more important, how do I solve this?

A container<derived> is-not-a container<base>. This is because you
could do:

container<derived*> d;
container<base*>& b = d; //not allowed, but pretend for now
b.push_back(new base()); //no problem
//now d contains a base object! ALERT!

So, instead you have to create a new container. e.g.

void f(container<base> const& cont);

//use range constructor:
f(container<base>(d.begin(), d.end()));

Tom
 
P

Philippe Guglielmetti

07.10.2004 16:26:10
Hi, suppose i've got a nice tree of polymorphic types, like an abstract
base class shape and some subclasses like circle, traingle and square.
Now i also happen to have a list of pointers to triangles (so of type
list<triangle *>) and i want to pass this list to a function that
accepts a list of shapes (so the parameter is of type list<shape *>).
How can I cast the triangle list to a list of shapes?
It is VERY dangerous to combine STL with pointers.
Have a look at my article http://www.codeproject.
com/vcpp/stl/polycontainer.asp for a cleaner approach.
Philippe Guglielmetti - www.goulu.net
 
H

Howard

Philippe Guglielmetti said:
07.10.2004 16:26:10

It is VERY dangerous to combine STL with pointers.
Have a look at my article http://www.codeproject.
com/vcpp/stl/polycontainer.asp for a cleaner approach.
Philippe Guglielmetti - www.goulu.net

I don't see what you mean by it being "VERY dangerous" to use pointers in
std containers. I do it all the time. Your two points in that article
refer simply to minor problems that are easy to overcome, in my opinion, not
hazards that make it dangerous to use. It's the same as having an array of
pointers...as long as you know what you're doing, they're easy to handle.
You may have to deal with ownership problems (relating to who's in charge of
deleting), and you may have to implement your own functions for comparison
(for sorting), but those are just things you have to do, not hazards. And
then again, you may not even have those problems. I don't, because I don't
copy between containers and I don't sort my data. But I do use vectors of
pointers to store pointers to base classes, so that I can make use of the
vector's good qualities (compared to arrays), and make use of polymorphism
with the objects I'm pointing to.

-Howard
 
D

David Kalkwarf

Philippe Guglielmetti said:
07.10.2004 16:26:10

You cannot cast your triangle list to a shape list no more than you can cast
a list of doubles to a list of shapes: Don't confiuse the type the list
contains with the list itself.

I suggest making your list of triangles a list of shapes. If you are truly
polymorphic, then you should have no problems. If you need to call a
function that is specific to triangles, then cast your Shape pointer to a
Triangle pointer and call it. There are ways to determine whether it is
actually a pointer to a Triangle, but that is another topic.


Dave
 
Joined
Nov 16, 2006
Messages
5
Reaction score
0
STL Containers - vector and polymorphism

I have a base class Employee, and two derived classes FullTimeEmp and PartTimeEmp.

I used an stl container - vector this way....

vector<Employee> workers;

I use 'workers' to store all, that is FullTimeEmp, PartTimeEmp and Employee. When I access them through workers.at(i) and try to call a virtual method in the classes- getPay()...it doesn't work. It keeps calling the Employee getPay() . I want it to call each differently depending on whether its a PartTimeEmp or FullTimeEmp accessed. Help! How do I achieve polymorphism?

Jairus
 

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,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top