Dav*_*vid 16 c++ idioms pimpl-idiom
我想使用pimpl成语来避免我的库的用户需要我们的外部依赖(如boost等),但是当我的类被模板化似乎是不可能的,因为方法必须在标题中.有什么我可以做的吗?
如果该类是模板化的,那么您的用户基本上需要编译它(这在最广泛使用的C++实现中确实如此),因此它们需要您的外部依赖项.
最简单的解决方案是将类的大部分实现放在非模板基类(或某些类的封装成员对象)中.解决那里的模块隐藏问题.
然后编写模板派生(或封闭)类以向其添加类型安全性.
例如,假设您有一个模板,它提供了在第一次访问时分配的惊人功能(省略了必要的复制构造函数,赋值,析构函数):
template <class T>
class MyContainer
{
T *instance_;
public:
MyContainer() : instance_(0) {}
T &access()
{
if (instance_ == 0)
instance_ = new T();
return *instance_;
}
};
Run Code Online (Sandbox Code Playgroud)
如果您希望将"逻辑"分成非模板基类,则必须以非模板方式对行为进行参数化,也就是说,使用虚函数:
class MyBase
{
void *instance_;
virtual void *allocate() = 0;
public:
MyBase() : instance_(0) {}
void *access()
{
if (instance_ == 0)
instance_ = allocate();
return instance_;
}
};
Run Code Online (Sandbox Code Playgroud)
然后,您可以在外层添加类型感知:
template <class T>
class MyContainer : MyBase
{
virtual void *allocate()
{ return new T(); }
public:
T &access()
{ return *(reinterpret_cast<T *>(MyBase::access())); }
};
Run Code Online (Sandbox Code Playgroud)
即您使用虚函数允许模板"填写"依赖于类型的操作.显然,如果你有一些值得隐藏的商业逻辑,这种模式才会真正有意义.