Boost logo

Boost Users :

Subject: Re: [Boost-users] [smart_ptr]intrusive_ptr suggestion
From: Gottlob Frege (gottlobfrege_at_[hidden])
Date: 2010-08-15 00:58:22


On Thu, Aug 12, 2010 at 10:56 AM, gast128 <gast128_at_[hidden]> wrote:
> Andrew Holden <aholden <at> charteroaksystems.com> writes:
>
>>
>> On August 11, 2010 5:35 PM, gast128 wrote:
>> > <snip>
>> >
>> >> Perhaps you should initialize the reference count to zero in the
>> >> constructor of IFoo, instead of initializing it to 1.
>> >>
>> >> In Christ,
>> >> Steven Watanabe
>> >
>> > Yes but I think it is more natural that the ref count starts at 1 for a
> ref counted object. Thats at least the
>> COM protocol
>>
>> It's a slightly different situation. COM is designed for manual reference
> counting. It assumes that each
>> raw pointer, including the one returned from the constructor, counts as a
> reference.  For boost intrusive
>> pointers, the count is the number of intrusive pointers referencing the
> object.  Until you assign the
>> object to one, that count is zero.
>
> Not sure if this adresses my problem. intrusive_ptr is used in situations
> where the object or some other mechanism keeps tracking of its lifetime.
> intrusive_ptr only guarantees to call 'intrusive_ptr_add_ref'
> and 'intrusive_ptr_release' on construction and destruction of the
> intrusive_ptr.  The most used scenario is probably objects which are ref
> counted. The count doesn't need to be the number of intrusive_ptr's on the
> object; it can be larger than that.
>
> Objects which start with a ref count of 1 get the previously described
> problem. Afaik is that also the most used scenario. Objects with reference
> count of 0 shouldnt be alive.
>
>

The ref count is a count of *references* - how many pointers point to
it, whether they are intrusive_ptrs or others:

KFoo * k = new KFoo; k.ref++; //there is one pointer referencing
it, manually update count
intrusive_ptr<KFoo> ik = k; // there are 2 pointers referencing it,
automatically update count
(void) new KFoo; // there are 0 pointers referencing it, count
should be 0 (and obviously we have a leak)

having said that, I agree a wrapper for new would be nice - in
particular one that returned a smart pointer:

intrusive_ptr<KFoo> ik2 = new_intrusive<KFoo>(); // returns
intrusive_ptr, count is 1
(void)new_intrusive<KFoo>(); // returns intrusive, not assigned to
variable, so returned temp goes out of scope - no leak

the problem is with constructor args. ie what if KFoo constructor takes params:

new KFoo(a,b,c);

new_intrusive<KFoo>(a,b,c);

this can be done with templates, but you run into "the forwarding
problem" (google it). C++0x should fix that.
If we were designing C++ from scratch today, maybe plain ol' new would
return a smart pointer, instead of a raw one.

By the way, What I've done once in the past is put the 'false' in the template:

MyIntrusive<KFoo, false> ik3 = new KFoo(a,b,c); // false - don't incr
the ref count

that means technically MyIntrusive<KFoo, true> and MyIntrusive<KFoo,
false> are 2 distinct types, but with some fancy cast operators and
constructors, you can make them interchangeable (with correct ref
counting!). But it is a bit of work just to get a nicer looking
constructor line.

Tony


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net