Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2004-10-28 07:19:40

Oleg Fedtchenko wrote:
> But the owner may be not an immediate
> class-container-of-the-member or its derivative but any
> arbitrary class like this:
> class A
> {
> public:
> WORD m_wData;
> };
> class B
> {
> public:
> A a;
> friend shared_ptr<WORD> GetData( shared_ptr<B> this_ )
> {
> return shared_ptr<WORD>(
> &this_->a.m_wData,
> boost::bind( &shared_ptr<A>::reset, this_ )
> );
> }
> };
> In this case we must create overridden functions for every
> owner type to correctly specify pointer to a member.


> And what about when A::m_wData is private?

Well, it depends on the actual level of privacy. Clearly a member whose
address is always exposed to the world isn't really private, regardless of
its access specifier.

But that aside, depending on the level of coupling between A and B, B should
either be a friend of A, or it must go via an analogous mechanism to obtain
WORD* from A*:

// in A
friend shared_ptr<WORD> GetData( shared_ptr<A> this_ )
     return shared_ptr<WORD>(
         boost::bind( &shared_ptr<A>::reset, this_ )

// in B
friend shared_ptr<WORD> GetData( shared_ptr<B> this_ )
     shared_ptr<A> pa( &this_->a,
         boost::bind( &shared_ptr<B>::reset, this_ ) );

     return GetData( pa );

Yes, this is not very efficient. But it's encapsulated (which is pretty much
the only point of making the data members "private" in this case.) That is,
you can change B::a from

    A a;


    shared_ptr<A> pa;

without changing the client code, or you could even generate the A
dynamically inside GetData. Similarly, you can change A::m_wData to

Another shared_ptr advantage is that weak_ptr works.

> Don't you think this is the better variant:
> template<class Z>
> shared_ptr<WORD> A::GetData( shared_ptr<Z> owner )
> {
> return shared_ptr<WORD>(
> &m_wData,
> boost::bind( &shared_ptr<Z>::reset, owner )
> );
> }

This is error-prone. I can pass any shared_ptr as an owner, regardless of
whether it actually owns *this.

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