Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Newbie question about 'boost::shared_ptr'

Reply
Thread Tools

Newbie question about 'boost::shared_ptr'

 
 
for.fun@laposte.net
Guest
Posts: n/a
 
      10-21-2005
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.

 
Reply With Quote
 
 
 
 
Zara
Guest
Posts: n/a
 
      10-21-2005
On 21 Oct 2005 08:23:47 -0700, http://www.velocityreviews.com/forums/(E-Mail Removed) 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 Yublic 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!



 
Reply With Quote
 
 
 
 
Kristo
Guest
Posts: n/a
 
      10-21-2005
(E-Mail Removed) 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

 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      10-21-2005
Zara wrote:
>
> Suppose:
>
> class Yublic 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)
 
Reply With Quote
 
Razzer
Guest
Posts: n/a
 
      10-21-2005
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?

 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      10-21-2005
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)
 
Reply With Quote
 
Razzer
Guest
Posts: n/a
 
      10-21-2005

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)


 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      10-21-2005
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)
 
Reply With Quote
 
Jack Saalweachter
Guest
Posts: n/a
 
      10-22-2005
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.
 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      10-23-2005
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)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
VONAGE Newbie w/newbie question New_kid@nowhere.new VOIP 0 08-11-2007 01:40 PM
another newbie question from another newbie.... Lee UK VOIP 4 05-17-2005 04:10 PM
newbie: cisco vlan newbie question No Spam Cisco 3 06-07-2004 10:02 AM
dumb newbie question (or newbie dumb question) Jerry C. Perl Misc 8 11-23-2003 04:11 AM
Newbie! I'm a newbie! What's wrong with this program? Id0x Python 4 07-20-2003 11:40 PM



Advertisments