可以使用哪种技巧来最小化实现pImpl类的工作量?
部首:
class Foo {
struct Impl;
boost::scoped_ptr<Impl> self;
public:
Foo(int arg);
~Foo();
// Public member functions go here
};
实现:
struct Foo::Impl {
Impl(int arg): something(arg) {}
// All data members and private functions go here
};
Foo::Foo(int arg): self(new Impl(arg)) {}
Foo::~Foo() {}
// Foo's public functions go here (and they refer to data as self->something)
如何使用Boost,可能继承,CRTP或其他技巧来避免尽可能多的样板代码?运行时性能不是问题。
答案 0 :(得分:5)
从Loki实施pimpl可能是一个很好的答案。另请参阅DDJ Article。
答案 1 :(得分:1)
这是可能的,但是天真的实现并不是你想要的。
问题在于模板通常是内联的,天真的实现方式是:
template <class Object>
class Pimpl
{
public:
explicit Pimpl(Object* obj): mObject(obj) {}
~Pimpl() { delete mObject; }
// either deep copy or no copy
private:
Object* mObject;
};
现在问题是你不希望在头文件中知道Object
(不是为了二进制兼容性,而是为了依赖管理)。如果Object
未知,则您无法直接实施Destructor
,Copy Constructor
和Assignment Operator
...
然而问题远非无法解决! Boost确实为shared_ptr
解决了这个问题。
这个想法是在构造函数中传递第二个项目,它将负责释放第一个项目的内存,并且将提供一个很好的默认实现。
当然,这是间接的。
namespace detail {
template <class Object>
struct Deleter { virtual void do(Object*) = 0; };
}
template <class Object>
class Pimpl
{
public:
typedef detail::Deleter<Object> deleter_type;
typedef boost::shared_ptr<deleter_type> deleter_pointer;
Pimpl(std::auto_ptr<Object> obj, deleter_pointer del);
~Pimpl();
Pimpl(const Pimpl&);
Pimpl& operator(const Pimpl&);
private:
Object* mObject;
deleter_pointer mDeleter;
};
这是C ++中的经典习语,增加了另一层次的间接性:)