$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Vladimir Batov (batov_at_[hidden])
Date: 2007-10-13 22:27:21
From: "Peter Dimov" <pdimov_at_[hidden]>
>> Anyway, I see you'd been preparing your implementation for Boost but it
>> does
>> not seem to have ever made it. That's unfortunate. How come it was
>> abandoned
>> and sent to the fringes of Yahoo archives?
>
> I have a "policy" of not proposing libraries that I don't use. impl_ptr
> was
> a nice experiment, but shared_ptr happens to satisfy all my
> implementation-hiding needs. :-)
That's fair enough. I myself certainly always use shared_ptr-based Pimpl.
However, due to specificity of my task I tend to use Pimpls with pointer
semantics only. In this discussion thread as soon as I mentioned Pimpl
people asked for value semantics and I believe that's reasonable. Are you
saying you've been using shared_ptr for Pimpls with value semantics? Then, I
guess, you'd have to explicitly write Pimpl(Pimpl const&), Pimpl::op=(),
Pimpl::op==(). Something straightforward like
template<class T>
class Pimpl
{
public:
Pimpl(Pimpl const that) : impl_(new T(*that.impl_)) {}
Pimpl& operator=(Pimpl const& that) const { *impl_ = *that.impl_; return
*this; }
bool operator==(Pimpl const& that) const { return *impl_ =
*that.impl_; }
private:
class Implementation;
boost::shared_ptr<Implementation> impl_;
};
does not cut it as it does not compile unless Pimpl::Implementation is
visible. So, we have to apply the same incomple-type management technique as
deployed in shared_ptr and your other impl_ptr. Like
template<class T>
class Pimpl
{
public:
Pimpl(Pimpl const that) : impl_(trait_->copy(*that.impl_)) {}
Pimpl& operator=(Pimpl const& that) const { trait_->assign(*impl_,
*that.impl_); return *this; }
bool operator==(Pimpl const& that) const { return
trait_->compare(*impl_, *that.impl_); }
private:
class Implementation;
boost::shared_ptr<Implementation> impl_;
trait* trait_;
};
and that seems like a serious hassle unless generalized. So, it feels the
Pimpl situation is begging for your impl_ptr. Don't you agree?
Unfortunately, neither your impl_ptr nor Alan Griffith grin_ptr seem to be
complete. Alan's implementation is very basic and does not seem to handle
run-time polymorphic classes. Your impl_ptr is better in that regard and
closer to shared_ptr (for obvious reasons :-)). However, dynamic_traits
extends incomplete-type management only onto copy when I feel it needs to do
the same for assignment and comparison. I do not feel impl_ptr's approach to
assignment via deletion and copy construction is 100% kosher.
Ideally, impl_ptr and shared_ptr ought to share the same scaffolding with
different deep/shallow-copy policies. It's sad, it has not worked out that
way.
Getting back to Pimpl, I feel that a thin interface layer on top of
shared_ptr or impl_ptr would alleviate much annoyance while writing Pimpls.
It can be as simlpe as
class Test1 : boost::pimpl<Test1, pointer_semantics>
{
only Test interface here
};
class Test2 : boost::pimpl<Test2, value_semantics>
{
only Test interface here
};
So, I guess, my question is how would you suggest I approach the issue? I'd
really like to hear you view on the subject.
Best,
Vladimir.