Boost logo

Boost :

From: Oleg Fedtchenko (BoostOleg_at_[hidden])
Date: 2004-10-15 03:12:32

>> 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(
>> {...}
>> But it's good if this class will never be used as an object
>> (nondynamic) data-member inside another owner.
>> Also it's good when we create shared_ptr using ptrOwner outside
>> a class because we can pass in a shared_ptr of any owner.

> Larry Evans wrote:
> This is unclear to me. Could you provide an example?

The Parse above is a function-member of a class DocActiveX (I forgot
to specify this). Therefore shared_ptr ptrOwner has DocActiveX as
its parameter.

But if an object of DocActiveX is a member of another class like this:

    class Superclass
        DocActiveX doc;

then parameter ptrOwner in the function DocActiveX::Parse (see above)
must be of type shared_ptr<Superclass>:

     shared_ptr<Tree> Parse( shared_ptr<Superclass> ptrOwner)
         shared_ptr<Tree> ptrMember( &m_Tree, ptrOwner);
         return ptrMember;

because ptrOwner is what ought to be deleted when all shared_ptr's to
m_Tree are released.

To resolve this issue the function Parse accepting owner of any type
can be written in a templated form:

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

But such a templated function has its own drawbacks, and there is an
alternative to it. Please, read this email
on that.

The issue about the owner type doesn't raise when shared_ptr to a member
is created outside a class containing that member
(e.g. inside an actual owner):

      Tree* Parse()
          Tree* ptrMember = &m_Tree;
          return ptrMember;

      void SomeClass::SomeFunc()

          shared_ptr<Superclass> pSuper(new Superclass);
          shared_ptr<Tree> ptrTreeHere( pSuper->doc.Parse(), pSuper);


But we can easily by mistake put some wrong owner instead of *pSuper*:

          shared_ptr<Tree> ptrTreeHere( pSuper->doc.Parse(), this);

// it's wrong because *this* cannot be deleted on destructing ptrTreeHere
// only dynamically allocated owner can be passed in the Parse
// and *this* can point to an object data-member (nondeletable using
// op *delete*) of some other class

And the next is clearer, isn't it?
And Parse below can have the only instance (as it's not templated).

      member_ptr<Tree> Parse()
          member_ptr<Tree> ptrMember( &m_Tree);
          return ptrMember;
          // deletable owner of m_Tree gets into ptrMember
          // from m_Tree inside its CTOR

      void Superclass::SomeFunc()



The proposed smart pointer member_ptr is described at

Oleg Fedtchenko

recommended thread entry

Boost list run by bdawes at, gregod at, cpdaniel at, john at