
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