October 19, 2005
On Wed, 19 Oct 2005 10:33:07 -0500, Larry Evans <cppljevans@cos-internet.com> wrote:
> On 10/18/2005 03:08 PM, Regan Heath wrote:
>> On Tue, 18 Oct 2005 11:32:49 -0500, Larry Evans
> [snip]
>>> Couldn't:
>>>
>>>    int refs = 0;
>>>
>>> be changed to:
>>>
>>>    int* refs = null;
>>>
> [snip]
>>> and eliminate:
>>>
>>>    RefPtr parent;
>>>
>>> altogether?
>>   Perhaps. However, you need to synchronize access to that integer. My code  synchronizes on the class, you would have to use some sort of  InterlockedIncrement function or similar.
>
> Ah!  I hadn't considered synchronization. But then couldn't the
> refs be encapsulated in another class to do this:

What advantage do you see in using 'another' class as opposed to doing what I did?

> class RefPtr
> {
>    RefPtr parent;
>    Object resource = null;
>
>    class RefCount
>    {
>      int num_refs = 0;
>
>      int increment()
>      {
>         //sychronized increment
>      }
>
>      int decrement()
>      {
>         //synchronized decrement
>      }
>
>
>    }//end RefCount class
>
>    RefCount refs = null;
>
>    ...
>
> }//end RefPtr class

The only difference I see is that the shared reference count no longer contains the reference to resource. To my mind the count and the reference to the resource belong together. That said, my implementation did have an extra reference to the resource hanging around.

> OK, now I'm probably showing my ignorance of how D differs from C++.  My
> understanding is that, since RefCount is a class, it's allocated on
> the heap.

Correct.

> Also, based on the original code, which contained:
>
>    resource = res;
>
> I'm assuming that the assert in the following code passes:
>
>    this(RefPtr rhs)
>    {
>      resource = rhs.resource;
>      refs = rhs.refs;
>      refs.increment();
>      assert(refs is rhs.refs);
>    }

Yes, it should.

> IOW, the reference count is shared between rhs and this.

Yes.

Regan
October 19, 2005
On 10/19/2005 03:43 PM, Regan Heath wrote:
> On Wed, 19 Oct 2005 10:33:07 -0500, Larry Evans  
[snip]
>> Ah!  I hadn't considered synchronization. But then couldn't the
>> refs be encapsulated in another class to do this:
> 
> What advantage do you see in using 'another' class as opposed to doing  what I did?
It makes the purpose of the RefPtr members clearer.  I was confused,
initially, about the purpose of parent.  Maybe my OOPS (see next few
lines) obscured this advantage.
> 
>> class RefPtr
>> {
>>    RefPtr parent;
OOPS.  The above should be removed.
>>    Object resource = null;
>>
>>    class RefCount
>>    {
>>      int num_refs = 0;
>>
>>      int increment()
>>      {
>>         //sychronized increment
>>      }
>>
>>      int decrement()
>>      {
>>         //synchronized decrement
>>      }
>>
>>
>>    }//end RefCount class
>>
>>    RefCount refs = null;
>>
>>    ...
>>
>> }//end RefPtr class
> 
> 
> The only difference I see is that the shared reference count no longer  contains the reference to resource. To my mind the count and the reference  to the resource belong together. 

Well, they are, in RefPtr.  OTOH, I can see where you could put them
together in RefCount and rename it to something like ResourceCount,
which would essentially be the type of your parent.  Then you could
just remove RefPtr.resource since it's now
RefPtr.refs.resource.  But then that's an extra indirection
which, AFAICT, has no advantage.

> That said, my implementation did have an  extra reference to the resource hanging around.

And that extra reference was confusing to me as well as
taking extra space.
October 19, 2005
On 10/19/2005 03:43 PM, Regan Heath wrote:
> On Wed, 19 Oct 2005 10:33:07 -0500, Larry Evans  
[snip]
>> I'm assuming that the assert in the following code passes:
>>
>>    this(RefPtr rhs)
>>    {
>>      resource = rhs.resource;
>>      refs = rhs.refs;
>>      refs.increment();
>>      assert(refs is rhs.refs);
>>    }
> 
> 
> Yes, it should.
> 
>> IOW, the reference count is shared between rhs and this.
> 
> 
> Yes.

Now, I'm guessing a "deep copy" of the resource would be is done with:

    resource = new Object(rhs.resource)

although this isn't relevant to the current discusssion about
smart pointers.  I'm just checking my understanding.  Or maybe
the above just does a "level-1" copy.  Maybe nows the time
to actually try some D and see ;)
October 19, 2005
On Wed, 19 Oct 2005 16:22:56 -0500, Larry Evans <cppljevans@cos-internet.com> wrote:
> On 10/19/2005 03:43 PM, Regan Heath wrote:
>> On Wed, 19 Oct 2005 10:33:07 -0500, Larry Evans
> [snip]
>>> I'm assuming that the assert in the following code passes:
>>>
>>>    this(RefPtr rhs)
>>>    {
>>>      resource = rhs.resource;
>>>      refs = rhs.refs;
>>>      refs.increment();
>>>      assert(refs is rhs.refs);
>>>    }
>>   Yes, it should.
>>
>>> IOW, the reference count is shared between rhs and this.
>>   Yes.
>
> Now, I'm guessing a "deep copy" of the resource would be is done with:
>
>      resource = new Object(rhs.resource)

No. D has no built in deep copy functionality. Instead it's customary to define a 'dup' method the class, so the above would read:

resource = rhs.resource.dup();

> although this isn't relevant to the current discusssion about
> smart pointers.  I'm just checking my understanding.  Or maybe
> the above just does a "level-1" copy.  Maybe nows the time
> to actually try some D and see ;)

Sounds like a plan. :)

Regan
October 19, 2005
On Wed, 19 Oct 2005 16:06:02 -0500, Larry Evans <cppljevans@cos-internet.com> wrote:
> On 10/19/2005 03:43 PM, Regan Heath wrote:
>> On Wed, 19 Oct 2005 10:33:07 -0500, Larry Evans
> [snip]
>>> Ah!  I hadn't considered synchronization. But then couldn't the
>>> refs be encapsulated in another class to do this:
>>  What advantage do you see in using 'another' class as opposed to doing  what I did?

> It makes the purpose of the RefPtr members clearer.  I was confused,
> initially, about the purpose of parent.  Maybe my OOPS (see next few
> lines) obscured this advantage.

Nah. I would re-organise as follows:

>>> class RefPtr
>>> {
>>>    class ResCount
>>>    {
>>>      Object resource = null;
>>>      int num_refs = 0;
>>>
>>>      int increment()
>>>      {
>>>         //sychronized increment
>>>      }
>>>
>>>      int decrement()
>>>      {
>>>         //synchronized decrement
>>>      }
>>>    }//end ResCount class
>>>
>>>    ResCount ref = null;
>>>
>>>    ...
>>>
>>> }//end RefPtr class
>>   The only difference I see is that the shared reference count no longer  contains the reference to resource. To my mind the count and the reference  to the resource belong together.
>
> Well, they are, in RefPtr.  OTOH, I can see where you could put them
> together in RefCount and rename it to something like ResourceCount,
> which would essentially be the type of your parent.  Then you could
> just remove RefPtr.resource since it's now
> RefPtr.refs.resource.  But then that's an extra indirection
> which, AFAICT, has no advantage.

Indeed, I have done just that above.

>> That said, my implementation did have an  extra reference to the resource hanging around.
>
> And that extra reference was confusing to me as well as
> taking extra space.

True.

Regan
1 2
Next ›   Last »