Why does shared_ptr have a public reset() method

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Why does shared_ptr have a public reset() method

Axter
Why does boost::shared_ptr have a public reset() method?

Why is this method not private?

 

In reading the introduction for weak_ptr, it seems like its main purpose is
to cover up or control this opening to boost::shared_ptr.

http://www.boost.org/libs/smart_ptr/weak_ptr.htm

 

If boost::shared_ptr didn't have this type of public access, would there be
a need for the weak_ptr?

 

I can not find any example code that would justify the requirement for the
weak_ptr other than the code in above link.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Why does shared_ptr have a public reset() method

Ben Artin
In article <008001c6260b$a0b7be90$0f00a8c0@david>,
 "David Maisonave" <[hidden email]> wrote:

> I can not find any example code that would justify the requirement for the
> weak_ptr other than the code in above link.


You need weak_ptr when you have cycles in your object graph. For example:

struct C1;
struct C2;

struct C1 {
   shared_ptr<C2>    p;
}

struct C2 {
   shared_ptr<C1>    p;
}

C1* p1 = new C1();
shared_ptr<C1> c1(p1);

C2* p2 = new C2();
shared_ptr<C2> c2(p2);

c1.p = c2;
c1.p = c1;

Given this code, neither the object at p1 nor the object at p2 will ever be
destroyed, because the cyclic dependency prevents refcounts from ever going to
zero. If you change either shared_ptr to a weak_ptr, the code correctly disposes
of both objects when both smart pointers go out of scope.

Ben

--
I changed my name: <http://periodic-kingdom.org/People/NameChange.php>

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Why does shared_ptr have a public reset() method

Peter Dimov
In reply to this post by Axter
David Maisonave wrote:

> Why does boost::shared_ptr have a public reset() method?

Why shouldn't it? Can you explain the reasoning that lead you to this
question?

> Why is this method not private?

It's not used internally, so there is no need to make it private. reset() is
a simple shorthand for swapping your shared_ptr with a temporary
default-constructed one, then destroying the temp. You can also achieve the
same effect by assignment.

p = shared_ptr<T>(); // same as p.reset()

Don't tell me that your smart pointer doesn't support assignment. :-)

> In reading the introduction for weak_ptr, it seems like its main
> purpose is to cover up or control this opening to boost::shared_ptr.
>
> http://www.boost.org/libs/smart_ptr/weak_ptr.htm

This example is why weak_ptr doesn't have a get() member returning a raw
pointer. reset() is used for simplicity, you can also pretend that p is
simply destroyed instead of being reset.

> If boost::shared_ptr didn't have this type of public access, would
> there be a need for the weak_ptr?

Yes of course. The pointee can be destroyed without ever using reset.

> I can not find any example code that would justify the requirement
> for the weak_ptr other than the code in above link.

It's hard to explain the usefulness of weak_ptr with one simple example.

In short, weak_ptr allows you to keep an eye on a pointee without affecting
its lifetime. You can periodically check whether the pointee is still alive
and if so, obtain a shared_ptr to it (by using weak_ptr<>::lock). This
shared_ptr would now temporarily keep the pointee alive until you are
finished with it.

There is no single canonical use for weak_ptr. It's a versatile tool that
can be used in every situation that matches the above description. Some
people use for it to break shared_ptr cycles. Others use it instead of a raw
pointer to check for dangling pointers. It can be used in a video game to
store the current target of the unit or the current selection. It can be
used in a document editor as a 'weak' reference to a portion of the
document, if this portion can disappear. And so on.

The most often cited example is a cache. Imagine you having a collection of
immutable objects that are expensive to create, such as images that are kept
on disk. You receive a request from user code for image "test.tga" and give
it a shared_ptr<image> to it. Now if you keep a weak_ptr, you'll be able to
service the next request for "test.tga" without going to the disk if the
first client is still using it.

I believe that this last scenario is one of the reasons for adding a weak
reference to Java.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Why does shared_ptr have a public reset() method

Axter
In reply to this post by Axter
"Peter Dimov" <[hidden email]> wrote in message
news:<00f101c62659$d1264990$6507a8c0@pdimov2>...
> David Maisonave wrote:
>
> It's not used internally, so there is no need to make it private.
> reset() is
> a simple shorthand for swapping your shared_ptr with a temporary
> default-constructed one, then destroying the temp. You can also achieve
the
> same effect by assignment.
>
> p = shared_ptr<T>(); // same as p.reset()

Reading the weak_ptr introduction gave me a misunderstanding of what reset
does.
I thought reset just release the pointer without deleteing it if it was the
last referenced.
If it does delete it when it's the last reference, than it does make sense
to have it public.


> Don't tell me that your smart pointer doesn't support assignment. :-)

It not only supports assignment, but it also has the ability to assign to a
different policy type.

> There is no single canonical use for weak_ptr. It's a versatile tool
> that
> can be used in every situation that matches the above description. Some
> people use for it to break shared_ptr cycles.

I just ran a test on this, and it seems that boost::shared_ptr does result
in leaving memory leak in cycle logic.
However, when I tested my proposed smart_ptr, it does not have this problem.
It's able to correctly destroy the objects even in cycles.
The proposed boost::policy_ptr also has the same cycle problem like
boost::shared_ptr.
I don't understand why they're not able to resolve this in the destructor
call.
Either I'm missing something in my smart_ptr, or there's some extra wacky
logic in the boost::shared_ptr that's blocking deletion in cycles. (Which I
don't get)


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Why does shared_ptr have a public reset() method

Daniel Wallin
David Maisonave wrote:

> "Peter Dimov" <[hidden email]> wrote in message
>> There is no single canonical use for weak_ptr. It's a versatile tool
>> that
>> can be used in every situation that matches the above description. Some
>> people use for it to break shared_ptr cycles.
>
> I just ran a test on this, and it seems that boost::shared_ptr does result
> in leaving memory leak in cycle logic.
> However, when I tested my proposed smart_ptr, it does not have this problem.
> It's able to correctly destroy the objects even in cycles.

Then I guess you should start looking for bugs in your code..

It isn't a "problem" with boost::shared_ptr; it's a property of
reference counting and linking. But really, you should know this.

--
Daniel Wallin

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost