模板类的pimpl [英] pimpl for a templated class

查看:108
本文介绍了模板类的pimpl的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用pimpl成语来避免我的库的用户需要我们的外部依赖(例如boost等),但是当我的类是模板化的,似乎是不可能的,因为方法必须在标题。

I want to use the pimpl idiom to avoid having users of my library need our external dependencies (like boost, etc) however when my class is templated that seems to be impossible because the methods must be in the header. Is there something I can do instead?

推荐答案

如果类是模板化的,你的用户基本上需要编译它

If the class is templated, your users essentially need to compile it (and this is literally true in the most widely-used C++ implementations) and so they need your external dependencies.

最简单的解决方案是将你的类的大部分实现放在一个非常简单的实现中,模板基类(或一些类的封装成员对象)。解决模块隐藏问题。

The simplest solution is to put the bulk of your class's implementation in a non-template base class (or encapsulated member object of some class). Solve the module-hiding problem there.

然后编写模板派生(或包含)类以添加类型安全性。

And then write the template derived (or enclosing) class to add type safety to it.

,假设您有一个模板,提供了惊人的分配在第一次访问(省略必要的复制构造函数,分配,析构函数):

For example, suppose you have a template that provides the amazing ability to allocate on first access (omitting the necessary copy constructor, assignment, destructor):

template <class T>
class MyContainer
{
    T *instance_;

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

    T &access()
    {
        if (instance_ == 0)
            instance_ = new T();

        return *instance_;
    }
};

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

If you wanted the "logic" to be separated into a non-template base class, you'd have to parameterise the behaviour in the non-template way, which is to say, use virtual functions:

class MyBase
{
    void *instance_;

    virtual void *allocate() = 0;

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

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

        return instance_;
    }
};

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

Then you can add the type-awareness in the outer layer:

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

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

您使用虚拟函数允许模板填充类型相关的操作。显然,这种模式只有真正有意义的,如果你有一些商业逻辑是值得的隐藏的努力。

i.e. You use virtual functions to allow the template to "fill in" the type-dependent operations. Obviously this pattern would only really make sense if you have some business logic that is worth the effort of hiding.

这篇关于模板类的pimpl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆