Boost logo

Boost :

From: Oleg Fedtchenko (BoostOleg_at_[hidden])
Date: 2004-10-14 09:52:19


>> Oleg Fedtchenko wrote:
>>
>>
>> shared_ptr<Tree> Parse( shared_ptr<DocActiveX> ptrOwner)
>> {
>> shared_ptr<Tree> ptrMember( &m_Tree, ptrOwner);
>> return ptrMember;
>> }
>>
>> And corresponding ctor that passes over a deletable pointer to an
>> owner (ptrOwner) of a class member (p):
>>
>>
>> template <class Y, class Z>
>> shared_ptr( Y * p, shared_ptr<Z>& ptrOwner)
>> : px(p), pn(ptrOwner.pn)
>> {...}
>>
>> The body of the function must be aware of the type of an owner. It
>> prevents this code from being used in a DLL until the owner type is
>> well-known (e.g. declared in boost).

> Larry Evans wrote:
>
> Well, I think all the information needed is in shared_ptr::pn.
> After all, it knows the actual type of the owner. That was the
> reason for the two pointers, px and pn, in shared_ptr. The 2nd
> actually knows the type of the owner. Am I missing something?

Ok. I meant the function Parse above cannot accept ptrOwner pointing
to a type other than DocActiveX if its body is in a DLL.
This could be resolved by using a templated form of that function.
And its body could be placed in a DLL's header:

      template <class Z>
      shared_ptr<Tree> Parse( shared_ptr<Z>& ptrOwner)
      {
          shared_ptr<Tree> ptrMember( &m_Tree, ptrOwner);
          return ptrMember;
      }

But let's consider the next example:

class A
{
protected:
    B b;
    C c;
    . . .
    K k;

public:

      template <class Z>
      shared_ptr<B> GetB( shared_ptr<Z>& ptrOwner)
      {
          return shared_ptr<B>( &b, ptrOwner);
      }

      template <class Z>
      shared_ptr<C> GetC( shared_ptr<Z>& ptrOwner)
      {
          return shared_ptr<C>( &c, ptrOwner);
      }

      . . .

      template <class Z>
      shared_ptr<K> GetK( shared_ptr<Z>& ptrOwner)
      {
          return shared_ptr<K>( &k, ptrOwner);
      }
};

Isn't it too clogging compared with the following:

class A : public member_ptr_owner_base
{
protected:
    B b;
    C c;
    . . .
    K k;

public:

      shared_ptr<B> GetB();

      shared_ptr<C> GetC();

      . . .

      shared_ptr<K> GetK();
};

Parameter ptrOwner is not used as a pointer to an owner
is stored in a base class.

And the body of all the functions can be nontemplated
and kept in a cpp module (in a DLL too) without
dublicating their object code.

And one more thing. An owner of an object is specified
only once (at object creating time) and used then many
times (often automatically). But for templated function

      template <class Z>
      shared_ptr<B> GetB( shared_ptr<Z>& ptrOwner)
      {
          return shared_ptr<B>( &b, ptrOwner);
      }

we must specify an owner every time and easily can
pass in a shared_ptr other than pointing to the right
owner:

    shared_ptr<A> pA(new A);

    shared_ptr<SOME> pSome(new SOME);

    shared_ptr<B> pB = pA->GetB( pSome);

So who can say what is the better smart pointers to a class data-member:

using this shared_ptr CTOR

         template <class Y, class Z>
         shared_ptr( Y * p, shared_ptr<Z>& ptrOwner, bool to_enable)
         : px(p), pn(ptrOwner.pn)
         {
             if(to_enable)
             {
                 detail::sp_enable_shared_from_this(p, p, pn);
             }
         }
// parameter to_enable is used do distinguish this CTOR from
// existing CTOR
// template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
// {...}

or

using member_ptr

described at http://boostoleg.narod.ru/member_ptr.html

Oleg Fedtchenko
BoostOleg_at_[hidden]
http://boostoleg.narod.ru

recommended 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