2010-12-31 11 views
9

一般的なコンテナタイプを作成して、共通の1つのインタフェースを提供すると同時に、使用している内部コンテナを非表示にしようとしています。C++の汎用コンテナ

基本的に私はアイテムのコレクションを返すプラグインを持っており、プラグインが自分のコードが使用しているコンテナのタイプを認識したくないと思います。

以下の例のコードより良い方向に私を指摘できますか?

template<class C, typename I> 
class Container 
{ 
public: 
//... 

    void push(const I& item) 
    { 
     if(typeid(C) == typeid(std::priority_queue<I>)) 
     { 
      std::priority_queue<I>* container = (std::priority_queue<I>*)&_container; 
      container->push(item); 
     } 
     if(typeid(C) == typeid(std::list<I>)) 
     { 
      std::list<I>* container = (std::list<I>*)&_container; 
      container->push_back(item); 
     } 
     else 
     { 
      //error! 
     } 
    }; 

    private: 
    C _container; 
//... 
} 

おかげであなたは「共通のインターフェースを」書いた

+4

できます。それをしないでください。アプリケーションの設計に時間を費やして、静的に型指定されたコンテナを使用するようにします。 – ybungalobill

+1

私はより良い方向にあなたを指すことができます、確かに:**これをやろうとしないでください**。真剣に。それはあなたに何も得られません。ここで話す経験の声。 –

+6

なぜここにdownvote?それは完全に正当な質問です。答えが「このようにしないでください」であっても、それは依然として有効な質問でした。 – Tim

答えて

6

私はアイテムのコレクションを返すプラグインを持っており、プラグインが自分のコードが使用しているコンテナのタイプを認識したくないと思います。

あなたのプラグインがアイテムの彼らのコレクションにbeginendイテレータを提供して、あなたが合うように範囲を消費してもらいます。

イテレータの最大の利点は、データの使用方法(アルゴリズム、場合によってはプラグインデータを消費するアプリケーションコード)からデータが格納される方法(コンテナ)を完全に切り離すことができることです。

この方法では、プラグインがデータをどのように格納しているか気にする必要はなく、プラグインは一旦データを渡すと気にする必要はありません。

+0

あなたの答えはありがとうございます。しかし、このアプローチは、糸が現場に現れたときに毛がかったように見えました。たとえば、DataStoreプラグインには、さまざまなバリデータIDで複数のスレッドから呼び出せるget_events(int validator_id)メソッドがあります。 – Corvusoft

+2

@user:分かりません。イテレータインターフェイスはコンテナインターフェイスよりも並行性の問題がありません。反復処理中にコンテナをロックするか、反復処理するコンテナのコピーを作成します。 –

+0

+1。しかし、プラグインの戻り値を消費するコードを再コンパイルする必要性を避けることが望ましいと考えています。新しいプラグインが内部的に別のコンテナ型を使用する道路の下に作成された場合です。 'begin()'と 'end()'基底クラス(インタフェース)によって返されるイテレータを独自の権利で返す必要があり、それらに純粋な '演算子++()'と 'operator *()'を与える必要があるようです。等の方法;使用する各コンテナタイプに対して、正しいタイプのイテレータの対応するメソッドに転送する具象サブクラスを作成します。トリッキーなと思われる... –

0

あなたが知っているが、私はあなたが標準コンテナをラップ抽象クラスとサブクラスで何かのJavaスタイルを表示するつもりだったと確信していました。私はタイプIDの呼び出しの束を参照して驚いた...

しかし、なぜあなたはこれをしたいですか?ほとんどのコンテナは共通のインターフェイスを共有しており、SFINAEの力で特別なコードを書く必要はありません。テンプレートを使用してメソッドを直接呼び出すだけです。

EDIT:標準的なコンテナには仮想メソッドがないので、dynamic_castにはできません。

0

上記のクラスから始めて、プラグインに必要な最小限のインターフェイスを公開してください。次に、使用するコンテナの観点から実装します。これはコンテナアダプタと呼ばれ、std :: stackの実装方法です。

STLコンテナを複数使用するためのアダプタが本当に必要な場合は、std :: stackを見て、それを行う方法を示します。

typeidをオンにしないでください。どうしてでしょうか?

ところで、コンテナ自体を公開する必要がない限り、Jamesが示唆しているものと一緒に行ってください。

関連する問題