stl containers and polymorphism

Discussion in 'C++' started by Maurice Termeer, Oct 7, 2004.

  1. 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
     
    Maurice Termeer, Oct 7, 2004
    #1
    1. Advertising

  2. On Thu, 07 Oct 2004 16:26:10 +0200, Maurice Termeer
    <> wrote:

    >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.

    --
    Bob Hairgrove
     
    Bob Hairgrove, Oct 7, 2004
    #2
    1. Advertising

  3. Maurice Termeer

    Tom Widmer Guest

    On Thu, 07 Oct 2004 16:26:10 +0200, Maurice Termeer
    <> wrote:

    >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
     
    Tom Widmer, Oct 7, 2004
    #3
  4. 07.10.2004 16:26:10
    Maurice Termeer <> wrote in message
    <ck3jm2$jq$>

    > 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
     
    Philippe Guglielmetti, Oct 8, 2004
    #4
  5. Maurice Termeer

    Howard Guest

    "Philippe Guglielmetti" <> wrote in message
    news:4166b564$0$28018$...
    > 07.10.2004 16:26:10
    > Maurice Termeer <> wrote in message
    > <ck3jm2$jq$>
    >
    > > 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


    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
     
    Howard, Oct 8, 2004
    #5
  6. "Philippe Guglielmetti" <> wrote in message
    news:4166b564$0$28018$...
    > 07.10.2004 16:26:10
    > Maurice Termeer <> wrote in message
    > <ck3jm2$jq$>
    >
    > > 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?


    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
     
    David Kalkwarf, Oct 10, 2004
    #6
  7. Maurice Termeer

    Jairus

    Joined:
    Nov 16, 2006
    Messages:
    5
    Location:
    Africa, Kenya
    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
     
    Jairus, Nov 16, 2006
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Claudio Jolowicz

    unique objects and stl containers

    Claudio Jolowicz, Apr 9, 2004, in forum: C++
    Replies:
    11
    Views:
    2,050
    James Dennett
    Apr 10, 2004
  2. Krivenok Dmitry
    Replies:
    13
    Views:
    1,444
    Axter
    Jun 1, 2006
  3. Replies:
    7
    Views:
    555
    Pete Becker
    Jan 25, 2008
  4. Andrey Vul
    Replies:
    6
    Views:
    575
    James Kanze
    Oct 22, 2009
  5. Sebastian Mach
    Replies:
    5
    Views:
    315
Loading...

Share This Page