Newbie question about 'boost::shared_ptr'

Discussion in 'C++' started by for.fun@laposte.net, Oct 21, 2005.

  1. Guest

    Hi everybody,


    I just read the 'shared_ptr' doc from the Boost site (at
    http://www.boost.org/libs/smart_ptr/shared_ptr.htm)


    There is a point I do not understand !


    1/ Suppose you want to create a 'shared_ptr' on the 'MyClass' object

    2/ My instanciation code could like this :

    shared_ptr<MyClass> spMyClass(new MyClass);


    3/ You can note that my Smart Pointer constructor argument is of
    'MyClass *' type.

    4/ In the Boost documentation, you can find this :

    shared_ptr<T> p(new Y);


    ... which suppose that T and Y can be of different type.


    The problem is I can not understand how T can be different from Y.
    As the definition says, the Smart Pointer type 'shared_ptr<T>' is a T
    Smart Pointer (a smart T *) so the Smart Pointer argument should always
    be of type 'T *'


    => Is it possible to have different types for T and Y ? Why and how is
    it possible ?


    Thanks in advance for your reply.
     
    , Oct 21, 2005
    #1
    1. Advertising

  2. Zara Guest

    On 21 Oct 2005 08:23:47 -0700, wrote:

    >Hi everybody,
    >
    >
    >I just read the 'shared_ptr' doc from the Boost site (at
    >http://www.boost.org/libs/smart_ptr/shared_ptr.htm)
    >
    >
    >There is a point I do not understand !
    >
    >
    >1/ Suppose you want to create a 'shared_ptr' on the 'MyClass' object
    >
    >2/ My instanciation code could like this :
    >
    > shared_ptr<MyClass> spMyClass(new MyClass);
    >
    >
    >3/ You can note that my Smart Pointer constructor argument is of
    >'MyClass *' type.
    >
    >4/ In the Boost documentation, you can find this :
    >
    > shared_ptr<T> p(new Y);
    >
    >
    > ... which suppose that T and Y can be of different type.
    >
    >
    >The problem is I can not understand how T can be different from Y.
    >As the definition says, the Smart Pointer type 'shared_ptr<T>' is a T
    >Smart Pointer (a smart T *) so the Smart Pointer argument should always
    >be of type 'T *'
    >
    >
    >=> Is it possible to have different types for T and Y ? Why and how is
    >it possible ?
    >
    >
    >Thanks in advance for your reply.



    Suppose:

    class Y:public T {/*.....*/};

    Now you have a type Y different from T, but a pointer to Y may be used
    where a pointer to T is, such as in sared_ptr.

    To Make it work right, T should have a virtual destructor!
     
    Zara, Oct 21, 2005
    #2
    1. Advertising

  3. Kristo Guest

    wrote:
    > In the Boost documentation, you can find this :
    >
    > shared_ptr<T> p(new Y);
    >
    >
    > ... which suppose that T and Y can be of different type.
    >
    >
    > The problem is I can not understand how T can be different from Y.
    > As the definition says, the Smart Pointer type 'shared_ptr<T>' is a T
    > Smart Pointer (a smart T *) so the Smart Pointer argument should always
    > be of type 'T *'
    >
    >
    > => Is it possible to have different types for T and Y ? Why and how is
    > it possible ?


    It's possible if T is a parent (or grandparent, etc.) class of Y. It
    would then be legal to assign a Y* to a T*.

    Kristo
     
    Kristo, Oct 21, 2005
    #3
  4. Pete Becker Guest

    Zara wrote:
    >
    > Suppose:
    >
    > class Y:public T {/*.....*/};
    >
    > Now you have a type Y different from T, but a pointer to Y may be used
    > where a pointer to T is, such as in sared_ptr.
    >
    > To Make it work right, T should have a virtual destructor!
    >


    T does not have to have a virtual destructor. std::tr1::shared_ptr keeps
    track of the original type, and when it destroys the resource it deletes
    it through the pointer that was passed to the constructor.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, Oct 21, 2005
    #4
  5. Razzer Guest

    Pete Becker wrote:
    > T does not have to have a virtual destructor. std::tr1::shared_ptr keeps
    > track of the original type, and when it destroys the resource it deletes
    > it through the pointer that was passed to the constructor.


    So let's assume something like this:

    //Necessary header files included

    class X { public: ~X() { } };
    class Y : public X { public: ~Y() { } };

    int main( void )
    {
    std::tr1::shared_ptr<X> x(new Y());
    }

    Would shared_ptr call ~Y in this instance as well?
     
    Razzer, Oct 21, 2005
    #5
  6. Pete Becker Guest

    Razzer wrote:
    > Pete Becker wrote:
    >
    >>T does not have to have a virtual destructor. std::tr1::shared_ptr keeps
    >>track of the original type, and when it destroys the resource it deletes
    >>it through the pointer that was passed to the constructor.

    >
    >
    > So let's assume something like this:
    >
    > //Necessary header files included
    >
    > class X { public: ~X() { } };
    > class Y : public X { public: ~Y() { } };
    >
    > int main( void )
    > {
    > std::tr1::shared_ptr<X> x(new Y());
    > }
    >
    > Would shared_ptr call ~Y in this instance as well?
    >


    Yes. And it would do the same for

    shared_ptr<void>(new Y);

    That's why it's called a smart pointer. <g>

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, Oct 21, 2005
    #6
  7. Razzer Guest

    Pete Becker wrote:
    > Razzer wrote:
    > > Pete Becker wrote:
    > >
    > >>T does not have to have a virtual destructor. std::tr1::shared_ptr keeps
    > >>track of the original type, and when it destroys the resource it deletes
    > >>it through the pointer that was passed to the constructor.

    > >
    > >
    > > So let's assume something like this:
    > >
    > > //Necessary header files included
    > >
    > > class X { public: ~X() { } };
    > > class Y : public X { public: ~Y() { } };
    > >
    > > int main( void )
    > > {
    > > std::tr1::shared_ptr<X> x(new Y());
    > > }
    > >
    > > Would shared_ptr call ~Y in this instance as well?
    > >

    >
    > Yes. And it would do the same for
    >
    > shared_ptr<void>(new Y);
    >
    > That's why it's called a smart pointer. <g>


    What about:

    X *p = new Y;
    shared_ptr<X>(p);

    ?

    It seems, to me, that the template scheme used would have met its match
    in this instance.

    >
    > --
    >
    > Pete Becker
    > Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Razzer, Oct 21, 2005
    #7
  8. Pete Becker Guest

    Razzer wrote:
    >
    > What about:
    >
    > X *p = new Y;
    > shared_ptr<X>(p);
    >
    > ?
    >
    > It seems, to me, that the template scheme used would have met its match
    > in this instance.
    >


    shared_ptr only knows what it's privy to. You can subvert it if you try.
    This kind of coding, though, is bad news even if X has a virtual
    destructor. If you write code that traffics in raw pointers and
    shared_ptr objects that try to manage the same resource you're going to
    get burned.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, Oct 21, 2005
    #8
  9. Pete Becker wrote:
    > Razzer wrote:
    >
    >>
    >> What about:
    >>
    >> X *p = new Y;
    >> shared_ptr<X>(p);
    >>
    >> ?
    >>
    >> It seems, to me, that the template scheme used would have met its match
    >> in this instance.
    >>

    >
    > shared_ptr only knows what it's privy to. You can subvert it if you try.
    > This kind of coding, though, is bad news even if X has a virtual
    > destructor. If you write code that traffics in raw pointers and
    > shared_ptr objects that try to manage the same resource you're going to
    > get burned.
    >

    You're _always_ better off writing virtual destructors when you know
    you're going to be using inheritance. shared_ptr just happens to allow
    you to get away with /not/ doing the right thing.

    In any case, this is a Good Example of why some famous paradigm or
    another says, Thou Shalt Not Allocate Memory Outside Of The Constructor
    Call For A Smart Pointer. Always say "shared_ptr<X>(new Y);", never "X
    *x = new Y;" or even "Y *y = new Y;".

    I /think/ there is also a second reason. If I recall correctly, it goes
    something like this. Suppose you write:

    Y *y = new Y;
    shared_ptr<X> x(y);

    Now, suppose your constructor fails. It has to allocate memory of its
    own, after all, and this allocation could fail, and then an exception is
    thrown, and you run the risk of y leaking. You'd have to get all ugly
    and say something like:

    Y *y = new Y;
    try {
    shared_ptr<X> x(y);
    } catch (...) {
    delete y;
    }

    Long story short, you have to start bending over backwards and manually
    managing your memory ... which is exactly what smart points are supposed
    to save you from. If, however, you say:

    shared_ptr<X> x(new Y);

    something completely different happens. The Blessed Standard, I do
    believe, dictates that in this case, should x throw an exception during
    construction, the memory we allocated will automatically disappear, like
    magic. No memory leak, no manual memory management.


    So, Thou Shalt Not Allocate Memory Outside Of The Constructor Call For A
    Small Pointer, Lest Thee Lose Type Information And Incur Memory Leaks.
     
    Jack Saalweachter, Oct 22, 2005
    #9
  10. Pete Becker Guest

    Jack Saalweachter wrote:
    >>

    > You're _always_ better off writing virtual destructors when you know
    > you're going to be using inheritance. shared_ptr just happens to allow
    > you to get away with /not/ doing the right thing.
    >


    No, shared_ptr is deliberately designed to handle this case correctly.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
     
    Pete Becker, Oct 23, 2005
    #10
    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. Philippe Guglielmetti
    Replies:
    4
    Views:
    903
    tom_usenet
    Oct 9, 2003
  2. James Mastro

    boost::shared_ptr inside stl::list

    James Mastro, Nov 13, 2003, in forum: C++
    Replies:
    1
    Views:
    2,041
    Cy Edmunds
    Nov 13, 2003
  3. Toby Bradshaw
    Replies:
    6
    Views:
    1,767
    Kai-Uwe Bux
    Jun 2, 2006
  4. Colin Caughie
    Replies:
    1
    Views:
    724
    Shooting
    Aug 29, 2006
  5. zl2k
    Replies:
    4
    Views:
    632
Loading...

Share This Page