Boost logo

Boost :

From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2006-10-26 18:43:20


Err, my example is incorrect. Arrays need to be allocated with new[] and
destroyed with delete[].

But the technique is still valid. The following was tested with a compiler
so it works. :)

struct arr_type
{
    int a_[10];
    arr_type()
    {
        std::cout << "arr_type constructed\n";
    }
    ~arr_type()
    {
        std::cout << "arr_type destroyed\n";
    }
};

int main( int argc, char const * argv[] )
{
    boost::shared_ptr<arr_type> ap( new arr_type );
    std::cout << "ap constructed\n";
    boost::shared_ptr<int> ip( ap, &(ap->a_[3]) );
    std::cout << "ip constructed\n";
    std::cout << "ap reset begin\n";
    ap.reset();
    std::cout << "ap reset end\n";
    std::cout << "ip reset begin\n";
    ip.reset();
}

Of course you'll need to add the following shared_ptr constructor:

template <class Y>
shared_ptr( shared_ptr<Y> const & r, T * x ): px(x), pn(r.pn)
{
}

The output of the above program is this:

arr_type constructed
ap constructed
ip constructed
ap reset begin
ap reset end
ip reset begin
arr_type destroyed
ip reset end

A similar example can be given with shared_ptr< std::list<int> >, or
shared_ptr< std::vector<int> >.

--Emil Dotchevski

"Emil Dotchevski" <emildotchevski_at_[hidden]> wrote in message
news:BAY102-DAV1016EA8C29E6F1392C8129D4070_at_phx.gbl...
>>> OK, add reinterpret_pointer_cast (I don't see why not, we need
>>> reinterpret_pointer_cast for the same reasons we need reinterpret_cast)
>>> to
>>> my request list, but the aliasing request is different: it doesn't
>>> simply
>>> treat a shared_ptr<T> as a shared_ptr<Y>.
>>>
>> Do you have a use case for reinterpret_pointer_cast?
>
> Any use case of reinterpret_cast between unrelated pointer types is a use
> case for reinterpret_pointer_cast.
>
>> You don't need it to pass arbitrary shared_ptr<T>s into a function;
>> shared_ptr<void> works fine for that.
>
> I thought the same thing but Peter Dimov pointed out that you need to
> accomodate shared_ptr<void const> as well as shared_ptr<void volatile> and
> shared_ptr<void const volatile>, etc. So, instead of taking
> shared_ptr<void
> const volatile> in the aliasing constructor, it's just better to take
> shared_ptr<Y>. It doesn't really matter because all we do with is use its
> pn
> member, which is independent of the type of the shared_ptr.
>
>>> What I need is a shared_ptr constructor, which takes a shared_ptr and a
>>> raw
>>> pointer, and returns a shared_ptr of the type of the raw pointer which
>>> points the same object the raw pointer points, but shares ownership (the
>>> "pn" member of shared_ptr) with the original shared_ptr:
>>>
>> Why do you want this? So it will delete both pointers?
>
> I am not sure what "so it will delete both pointers" means, but I'm
> reasonably sure that's not what I want. :)
>
>> The code you've given would, I expect, have some serious problems. I
>> think one of the pointers would get leaked and if it was the one from
>> the original shared_ptr that leaked, a wrong deleter could be called
>> on the new pointer.
>
> The thing about shared_ptr is that the deleter has nothing to do with the
> px
> member of class shared_ptr. The px member is what operator*, operator->,
> and
> get() return. But px is not passed to the deleter when the object expires.
> Instead, the control block pointed to by the pn member of shared_ptr keeps
> the *original* pointer that was passed to the first of the (possibly) many
> shared_ptr objects that share ownership of a given object.
>
> The net effect of all this is that if somehow you change the px member of
> an
> existing shared_ptr, the object will not leak, and will be properly
> destroyed, no matter what px points to.
>
> With this in mind, consider this example:
>
> typedef int arr_type[10];
> shared_ptr<arr_type> pa( new arr_type );
> shared_ptr<int> pi( pa, &((*pa)[3]) ); //aliasing ctor
> pa.reset(); //won't destroy the array, pi keeps it afloat.
> (*pi) = 0; //zeroes the 4th int in the array.
> pi.reset(); //destroys the array passed to pa, not the int pi points.
>
> You can build a similar example for an object of class T being kept afloat
> by a shared_ptr<Y> to a member of type Y of the T object.
>
> --Emil Dotchevski
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk