自动化C ++类的pimpl - 有一个简单的方法吗?

时间:2009-10-25 17:18:45

标签: c++ templates build-process macros pimpl-idiom

Pimpl是很多C ++代码中的样板来源。它们似乎是宏,模板和一些外部工具帮助可以解决的组合,但我不确定最简单的方法是什么。 I've seen templates帮助完成一些提升但不是很多 - 你仍然需要为你试图包装的类的每个方法编写转发函数。有更简单的方法吗?

我正在想象一个用作制作过程一部分的工具。你希望你的公共标题是pimpl'd类,所以你提供一些输入文件,比如pimpl.in,列出你要包装的类(实现un-pimpl'd),然后检查该文件,生成pimpl类,并且在'make install'期间只安装它们的标题(不是原始类的标题)。问题是如果没有完整的C ++解析器,我没有看到任何方法可以做到这一点,甚至编译器供应商都无法做到这一点。也许这些类可以用某种方式编写,这使得外部工具的工作变得更容易,但我确信我最终会遗漏各种角落案例(例如模板化类和/或模板化成员函数)。

有什么想法吗?有没有其他人为这个问题找到解决方案?

3 个答案:

答案 0 :(得分:6)

不,没有一个简单的答案。 :-(我认为几乎每个OO专家都说“更喜欢构图而不是继承”),语言支持使构图比继承更容易。

答案 1 :(得分:2)

我并不是说这很好(只是想到的东西) 但您可以尝试重载运算符 - >

#include <memory>
#include <iostream>

class X
{
    public:
    void plop()
    {
        std::cout << "Plop\n";
    }
};

class PimplX
{
    public:
        PimplX()
        {
            pimpl.reset(new X);
        }
        X* operator->()
        {
            return pimpl.get();
        }
    private:
        PimplX(PimplX const&);
        PimplX& operator=(PimplX const&);
        std::auto_ptr<X>    pimpl;
};   


int main()
{    
    PimplX      x;

    x->plop();
}

答案 2 :(得分:0)

一种选择是使用接口类:

class ClassA {
  virtual void foo() = 0;
  static ClassA *create();
};

// in ClassA.cpp

class ImplA : public ClassA {
/* ... */
};
ClassA *ClassA::create() {
  return new ImplA();
}

但这会增加取得vtable函数指针的开销。

除此之外,我想不出任何这样的工具。正如你所说,解析C ++并非易事,而且还有其他语言存在问题(例如,C#或Java后期绑定所有内容,因此您可以在以后更改其内存中布局而不会出现问题)。 / p>