c++ - 用于模板类的 pimpl

标签 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_;
    }
};

如果你想把“逻辑”分离成一个非模板基类,你必须以非模板的方式参数化行为,也就是说,使用虚函数:

class MyBase
{
    void *instance_;

    virtual void *allocate() = 0;

public:
    MyBase() : instance_(0) {}

    void *access()
    {
        if (instance_ == 0)
            instance_ = allocate();

        return instance_;
    }
};

然后你可以在外层添加类型感知:

template <class T>
class MyContainer : MyBase
{
    virtual void *allocate()
        { return new T(); }

public:
    T &access()
        { return *(reinterpret_cast<T *>(MyBase::access())); }
};

即您使用虚函数来允许模板“填充”依赖于类型的操作。显然,只有当您有一些值得努力隐藏的业务逻辑时,这种模式才真正有意义。

关于c++ - 用于模板类的 pimpl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7858271/

相关文章:

c++ - 在 Windows 上制作期间未定义 Qt vulkan 类

c++ - 尾随数组习语

Android Studio 弄乱了巴西-葡萄牙语字符

c++ - 向 Pimpl 类添加单例功能

c++ - 如何正确包装第 3 方库结构?

c++ - 粉刺 : Avoiding pointer to pointer with pimpl

c++ - 一组高效的 3D 相交算法

c++ - 在 C++ 中使用 eigen3 进行继承和转换

c++ - 将指针 (T*) 转换或转换为两个常量 (T const * const) 指针

c++ - 类型向量化的适当通用习惯用法?