|
Boost : |
From: Oleg Fedtchenko (BoostOleg_at_[hidden])
Date: 2004-10-20 01:48:14
> Larry Evans wrote:
>
> I'm having trouble understanding. Could you provide example code,
> or indicate whether the following is even close to your meaning:
Yes. It's not exactly what I meant but it's closer.
I meant that an error could occur when passing a wrong owner in
a function like this:
template <class W>
shared_ptr<T> Parse( shared_ptr<W> ptrOwner)
{
shared_ptr<T> ptrMember( &a_member, ptrOwner);
return ptrMember;
}
because a_member must be a data-member of *ptrOwner itself or of any
of its data-members.
To reduce the possibility of this a class should contain a pointer
to its owner inside that class and take it only once (through a CTOR
or some set function). As you did in the next snippet.
> Larry Evans wrote:
>
> template<owner_id Id>
> struct an_owner
> : public other_id<Id>
> {
> typedef other_id<Id> other_type;
> typedef an_owner<other_type::the_id> other_owner_type;
> member_type a_member;
> shared_ptr<member_type> p_member;
> an_owner(void){}
> an_owner(shared_ptr<other_owner_type>const & a_other)
> : p_member(a_other, &other_owner_type::a_member)
> {}
> };
>
> int main()
> {
>
> {
> shared_ptr<an_owner<id1> > p1(new an_owner<id1>);
> shared_ptr<an_owner<id2> > p2(new an_owner<id2>(p1));
> }
>
> return boost::report_errors();
> }
Yes. The second CTOR is wrong CTOR because p2->p_member points to
p1->a_member which leads to an access violation after p1 is released.
But I think there is no way to avoid supplying a wrong owner.
> Larry Evans wrote:
>
> template<owner_id Id>
> struct an_owner
> : public other_id<Id>
> {
> typedef other_id<Id> other_type;
> typedef an_owner<other_type::the_id> other_owner_type;
> member_type a_member;
> shared_ptr<member_type> p_member;
> an_owner(void){}
> an_owner(shared_ptr<other_owner_type>const & a_other)
> : p_member(a_other, &other_owner_type::a_member)
> {}
> };
You use p_member to keep a ref count to an owner of a_member.
In this case the owner won't be deleted until p_member is released.
But p_member will be released when the owner is deleted.
It's a deadlock because the owner will never be deleted.
There must be used another method of storing a ref count
to an owner of a_member.
That's why member_ptr requires pointees (members and owners) to
be derived from a predefned base class. This base class
stores a raw pointer to a class owner (which excludes a deadlock
mentioned above).
It also stores a ref count with predefined add_ref() and release()
functions. The difference between member_ptr and intrusive_ptr is
that the member_ptr exposes through function get() a pointer of one
type and calls add_ref() and release() for a pointer of the second type.
Oleg Fedtchenko
The proposed smart pointer member_ptr is described at
http://boostoleg.narod.ru/member_ptr.html
thread entry
http://lists.boost.org/MailArchives/boost/msg73168.php
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk