Boost logo

Boost :

From: Vladimir.Batov_at_[hidden]
Date: 2008-03-31 20:17:06


...skipped the beginning which appears to be duplication of the previous
email

> Could you clarify if the base implementation pointer can or can not be
> initialized with a pointer to the implementation of the derived class?
There
> is something wrong in
>
> Base::Base(int k) : base(new BaseImpl(k)){}
> Derived1::Derived1(int k, int l) : Base(new Derived1Impl(k, l))

No, this initialization method is not allowed. One needs to use reset()
instead as you show below. I considered the syntax above and rejected it
on the grounds that it does not add new functionality (as reset() already
does that) and it is not generic enough as it won't work for "Derived2 :
public Derived1"

> Base::Base(int k) : base(null())
> {
> reset(new BaseImpl(k));
> }
>
> Derived1::Derived1(int k, int l) : Base(null<Base>())
> {
> reset(new Derived1Impl(k, l));
> }
>
> Could a class inherit privately from pimpl?
>
> class A : private pimpl<A>::value_semantics {...}

Well, I guess it can... although I am yet to see a compelling case to
actually do that. It'll deny all the functionality that is in pimpl_base
to the derived class(es).
 
> There is something that seams extrange to me. If the pimpl is there to
mask
> the implementation, doesn't adds the public inheritance of
> pimpl<A>::value_semantics some implemtation constraints?

I cannot think of any particular implementation constraints

> Note that public inheritance adds to the class interface the null()
> function, bool type conversion and ! operator, and adds also all the
> protected functions to the derevied classes.

I am not sure I understand. Is it a bad thing?

> Can we found always a null object for every class when pimpl is not
used?

null<T>() has boost::enable_if_c<is_pimpl<T>::value, T>::type so my
implementation only kicks in for pimpls.

> Can a class that inherits from a non pimpl class has its own private
impl?
>
> class A;
>
> class B : A, public pimpl<B>::value_semantics {...}
>
> How the B implementation has access to A?

I am not sure it is a good (from pimpl perspective) design. Pimpl is about
separation of interface and implementation and implementation hiding. By
inheriting from A we just threw all that out the window. So, doing that
for B implementation does not seem to have much value. Having said that,
if one indeed needs access to A inside B implementation, then keeping B*
inside B implementation seems to solve the problem. With regard to
handling polymorphic hierachies the Bridge description from GoF would be a
good start. That'll be fully applicable to the proposed pimpl.

> maybe we need something like that
>
> class B : public pimpl<B, A>::value_semantics {...}
>
> making the implementation of B inherit from A.

"making the implementation of B inherit from A" is

struct pimpl<B>::implementation : public A
{
}

That certainly makes sense (to me anyway).

> Could we inherit publicly from A and privatly from pimpl<B,
> A>::value_semantics?

Cannot comment on this one as I am not convinced we need that (see above).

> Can we manage with multiple inheritance?
> class A : public pimpl<A>::value_semantics {...};
> class B : public pimpl<B>::value_semantics {...};
> class C : public A, public B {...};

Sure... with all the relevant multiple-inheritance perks/drawbacks.

> How pimpl interacts with STL containers?
>
> stl::list<A> al;
> B b;
> al.push_back(b);
> // ...somewhere else
> A a =al.pop_back();
>
> How 'a' should behaves? like a A or like a B?

I presume

struct A : pimpl<A>::... {}
struct B : public A {}

Then the result depends if A is of value_semantics or pointer_semantics.
With pointer_semantics it behaves as, say, boost::shared_ptr would behave.
Otherwise, during copying B part will be chopped off. So, "A a" will
behave as A.

> The STL container user that
> shouldn't knowns nothing about A implementation, expect that it will
behaves
> as a A, but it think that 'a' will behaves like a B. How can we protect
from
> this situation?

I probably do not understand something as I still do not see what it is to
protect from. A pimpl-based class behaves as any ordinary class (as it is
in fact an ordinary class).

> Could we store a non polymorph pimpl object in shared memory?
> Could we store non polymorph pimpl objects in a container in shared
memory?

I am not convinced these special cases require anything from the pimpl.
Although these certainly need more effort from the developer. Issues and
means to deal with those seem to be the same as if one tried to store a
pointer or std::auto_ptr or a boost::shared_ptr in shared memory. Given
it's all in the developer's hands (implementation can be allocated
explicitly and then associated via reset()) it'll be the developer's pain.
This seems to be merely part of overall painful experience of dealing with
shared memory. :-)

> I hope that you will find good solutions to these problems.

So, do you find my answers to your satisfaction?

> In any case, I
> will apreciate that you include in the library documentation the
limitations
> of the approach, if there are any.

Thanks,
Vladimir.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk