2009-10-25 13 views
10

Pimplは多くのC++コードの定型文のソースです。マクロ、テンプレート、多少の外部ツールの組み合わせで解決できるもののように見えますが、最も簡単な方法は何か分かりません。 I've seen templatesこれは、持ち運びには役立ちますが、それほど多くはありません。巻き戻そうとしているクラスのすべてのメソッドの転送関数を作成する必要があります。簡単な方法がありますか?C++クラスの自動化を自動化する - 簡単な方法はありますか?

私はmakeプロセスの一部として使用されるツールを想像しています。パブリックヘッダがpimpl'dクラスであるようにしたいので、ラップしたいクラス(pimplで実装されていない)をリストしたpimpl.inなどの入力ファイルを用意し、そのファイルを調べ、 pimplクラスが生成され、 'make install'中にヘッダー(元のクラスのヘッダーではない)だけがインストールされます。問題は、完全な吹き飛ばされたC++パーサーなしではこれを行う方法がないことです。コンパイラベンダーでさえ得られないものもあります。多分、クラスは外部ツールの仕事をより簡単にするような形で書くことができるかもしれませんが、私はあらゆる種類のコーナーケース(例えば、テンプレート化されたクラスやテンプレート化されたメンバ関数)を失うことになるでしょう。

アイデア?他の誰かがすでにこの問題の解決策を持っていますか?

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

// in ClassA.cpp 

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

しかしこれはvtableの関数ポインタをフェッチからオーバーヘッドを追加しない:

+0

レイジーC++は似た何かをする – Amnon

答えて

6

いいえ、簡単な答えはありません。 :-(私はほぼすべてのOOの専門家が "相続よりも組成を好む"と言っているが、相続よりも組成を非常に簡単にするための言語サポートがあると思う。

0

一つの選択肢ではなく、インタフェースクラスを使用することです。

それ以外は、私はそのようなツールを考えることはできません。あなたが言ったように、C++の解析は簡単ではなく、問題の少ない他の言語もあります(例:C#またはJavaのすべてのバインドが遅れているので、後で問題なくインメモリレイアウトを変更できます)。

+4

C#のほとんど明らかにしない「後期バインドすべて」面白いアイデアだ –

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(); 
} 
+0

、あなたはでしょうが。 Xオブジェクトに直接関数を呼び出すことになります。つまり、Xのヘッダーと定義を公開する必要があるため、Xは表示されません完全に不透明。一方で、主にABIのためにやっていて、クラスを不透明にしていない場合(また、ヘッダーが利用可能なときにユーザーがXを直接使用することを信用できます)、それは問題ないと思います。 –

+0

また、C++のクラス定義の中で定義されている関数は、暗黙的にインラインです。 PimplXのコンストラクタと演算子の定義をクラスから外して、呼び出し元をXのABIに結びつけないようにする必要があります。 –

関連する問題