templates and polymorphism

Discussion in 'C++' started by mscava@gmail.com, Feb 19, 2007.

  1. Guest

    I've created CoutedPtr<T> type to be able o track how many times
    pointer is being reference( for garbage collecting ). The problem is
    that the polymorphism doesn't work. e.g. CountedPtr<Bitmap> !=
    CountedPtr<Resource> although Bitmap IS Resource( I mean class
    Bitmap : public Resource ). How can I go around this obstacle? If you
    need more code just tell me...
     
    , Feb 19, 2007
    #1
    1. Advertising

  2. Ondra Holub Guest

    napsal:
    > I've created CoutedPtr<T> type to be able o track how many times
    > pointer is being reference( for garbage collecting ). The problem is
    > that the polymorphism doesn't work. e.g. CountedPtr<Bitmap> !=
    > CountedPtr<Resource> although Bitmap IS Resource( I mean class
    > Bitmap : public Resource ). How can I go around this obstacle? If you
    > need more code just tell me...


    Typical aproach is to create CountedPtr<BaseType>. I suppose you have
    to provide raw pointer to BaseTypeto constructor of
    CountedPtr<BaseType>. So it is simple, just use pointer to derived
    type:

    class BaseType
    {
    // Some declarations
    };

    class DerivedType: public BaseType
    {
    // Some declarations
    };

    CountedPtr<BaseType> p = new DerivedType;

    And you have polymorphis.
     
    Ondra Holub, Feb 19, 2007
    #2
    1. Advertising

  3. peter koch Guest

    On Feb 19, 1:54 pm, wrote:
    > I've created CoutedPtr<T> type to be able o track how many times
    > pointer is being reference( for garbage collecting ). The problem is
    > that the polymorphism doesn't work. e.g. CountedPtr<Bitmap> !=
    > CountedPtr<Resource> although Bitmap IS Resource( I mean class
    > Bitmap : public Resource ). How can I go around this obstacle? If you
    > need more code just tell me...


    If every class gets counted properly, and Bitmap is a Resource, then
    CountedPtr<BitMap> <= CountedPtr<Resource>, where the comparison will
    be < unless Bitmap is the only Resource instantiated.
    If that is not the case, I assume there is some problem with your
    code. If you are using the curiously recurring template pattern your
    "example" above misses something. It should be something like:
    Bitmap : public Resource, public CountedPtr<BitMap> {...
    (I assume that in other uses of CountedPtr<> you meant e.g.
    CountedPtr<BitMap>::value)

    /Peter
     
    peter koch, Feb 19, 2007
    #3
  4. Guest

    > Typical aproach is to create CountedPtr<BaseType>. I suppose you have
    > to provide raw pointer to BaseTypeto constructor of
    > CountedPtr<BaseType>. So it is simple, just use pointer to derived
    > type:
    >
    > class BaseType
    > {
    > // Some declarations
    >
    > };
    >
    > class DerivedType: public BaseType
    > {
    > // Some declarations
    >
    > };
    >
    > CountedPtr<BaseType> p = new DerivedType;
    >
    > And you have polymorphis.


    Problem is that this way CountedPtr will loose it's meaning, when I
    will be assigning raw pointer. The action I want to solve is
    CountedPtr<Bitmap> = CountedPtr<Resource>. And this makes me think of
    implementing somehow dynamic_cast...
     
    , Feb 19, 2007
    #4
  5. Guest

    > If every class gets counted properly, and Bitmap is a Resource, then
    > CountedPtr<BitMap> <= CountedPtr<Resource>, where the comparison will
    > be < unless Bitmap is the only Resource instantiated.
    > If that is not the case, I assume there is some problem with your
    > code. If you are using the curiously recurring template pattern your
    > "example" above misses something. It should be something like:
    > Bitmap : public Resource, public CountedPtr<BitMap> {...
    > (I assume that in other uses of CountedPtr<> you meant e.g.
    > CountedPtr<BitMap>::value)
    >
    > /Peter


    Well here is more exact code:

    vector< CountedPtr<Bitmap> > vec;
    // Function in my ResourceManager
    CounterPtr<Resource> Get( string& key )
    // This is the line where compiler says it want to get Bitmap passed,
    not Resource
    vec.push_back( RCM::Get( myKey ) );
     
    , Feb 19, 2007
    #5
  6. Guest

    I feel like I should formulate it otherwise. Can I cast templates?

    With normal pointers I would do:

    Bitmap* b;
    Resource* r = new Resource;
    b = dynamic_cast<Bitmap> r;

    But what if I want to do it with CountedPtr<T>?

    CountedPtr<Bitmap> = CountedPtr<Resource>; is not valid...

    Is there a way go around this?
     
    , Feb 19, 2007
    #6
  7. Guest

    On Feb 19, 6:54 am, wrote:
    > I've created CoutedPtr<T> type to be able o track how many times
    > pointer is being reference( for garbage collecting ). The problem is
    > that the polymorphism doesn't work. e.g. CountedPtr<Bitmap> !=
    > CountedPtr<Resource> although Bitmap IS Resource( I mean class
    > Bitmap : public Resource ). How can I go around this obstacle? If you
    > need more code just tell me...


    Check out boost's shared_ptr
    http://www.boost.org/boost/shared_ptr.hpp

    Specifically boost::dynamic_pointer_cast

    and

    shared_ptr::eek:perator=( const shared_ptr& rhs )

    This is some pretty detail oriented stuff. I'd recommend using boost's
    implementation of shared_ptr's to create garbage collection.
     
    , Feb 19, 2007
    #7
  8. Guest

    Ouw! Thanks Paul! Something I'm going to study. I'll try to implement
    it by myself. Thanks again.
     
    , Feb 19, 2007
    #8
  9. > With normal pointers I would do:
    >
    > Bitmap* b;
    > Resource* r = new Resource;
    > b = dynamic_cast<Bitmap> r;
    >
    > But what if I want to do it with CountedPtr<T>?
    >
    > CountedPtr<Bitmap> = CountedPtr<Resource>; is not valid...
    >
    > Is there a way go around this?


    Hi.

    If Resource is a base class of the derived class Bitmap then the above
    example should always fail. (As in a resource is not a bitmap. A
    bitmap is a resource. Maybe you meant to write 'Resource* r = new
    Bitmap' on the second line, then the example would make sense.)

    However if you wanted to allow assignemnt the other way, from wrapper
    of derived pointer to wrapper of base pointer.. as in
    CountedPtr<Resource*> = CountedPtr<Bitmap*>
    just as there is an imlicit conversion from a naked derived pointer to
    a base pointers. as in
    Resource* = Bitmap*

    Then you can overload the CountedPtr copy constructor to do just
    that.

    <CODE>

    template <class T>
    struct CountedPtr {

    CountedPtr(T t):t_(t) {}

    template <class T1>
    CountedPtr(CountedPtr<T1> &t1):t_(t1.t_) {} // copy constructor for
    different template type. So CountedPtr<T1> to CountedPtr<T> will work
    if there is a conversion from T1 to T

    T t_;
    };


    struct Base{};
    struct Derived: public Base {};

    inline void Test() {
    CountedPtr<Base*> cb(0);
    CountedPtr<Derived*> cd(0);
    cb = cd; // works
    }

    </CODE>

    Regards Patrik
     
    Patrik Kahari, Feb 20, 2007
    #9
    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. sapropel
    Replies:
    1
    Views:
    601
    Victor Bazarov
    May 14, 2004
  2. JKop
    Replies:
    3
    Views:
    505
  3. glen stark

    templates and polymorphism

    glen stark, Mar 28, 2006, in forum: C++
    Replies:
    2
    Views:
    282
    Stuart Redmann
    Mar 29, 2006
  4. Krivenok Dmitry
    Replies:
    13
    Views:
    1,478
    Axter
    Jun 1, 2006
  5. recover
    Replies:
    2
    Views:
    845
    recover
    Jul 25, 2006
Loading...

Share This Page