2012-02-28 28 views
2

私はおそらく完全にこれをベースにしていませんが、私はC#から来ていますので、事前にお詫び申し上げます。C++型消去/型カプセル化?タイプを発見

まず、私がやろうとしていることについてちょっと説明します。私は、私はその後、やりたいことは、工場のリストを持っている(STLベクトルやリストを言う)と、テンプレートの種類によってそれらを検索することができている

template<typename _Ty> 
class Factory 
{ 
public: 
    virtual std::shared_ptr<_Ty> Create() = 0; 
}; 

として私のコードで定義された工場出荷時の基本クラスを持っています。私は、その後のタイプを比較するための容器に方法のいくつかの種類を含めたい

class FactoryContainer 
{ 
    struct FactoryConcept { 
     virtual ~FactoryConcept() {} 
    }; 

    template< typename _Ty > struct FactoryModel : FactoryConcept { 
     FactoryModel(const _Ty& t) : factory(t) {} 
     virtual ~FactoryModel() {} 
    private: 
     _Ty factory; 
    }; 
    std::shared_ptr<FactoryConcept> factory; 

public: 
    template< typename _Ty > FactoryContainer(const _Ty& _factory) : 
     factory(new FactoryModel<_Ty>(_factory)) {} 
}; 

:これまでのところ、私は考え出した私は、私が思いついたいくつかの並べ替えの含むタイプのベクトルまたはリストが必要、

template<typename _Ty> bool isType(){...} 

の線に沿って何かが、私はそれを実装する方法まったくアイデアを持っていない、または私も型消去を使用した後のタイプを決定するとそこに右のトラックにしています。

EDIT: これはXYの問題であるとの複数のコメントの後、私は自分が行っていることを再強調することに決めました。

私は、Factory型(すべてのインスタンス化された任意のテンプレート型を含む)のstlコンテナを持ち、テンプレート型から1つを抜き出すことができます。 私はこれを行うには(が最良の方法ではないかもしれません)型のカプセル化コンテナクラスを使用して、含まれている型が指定されたテンプレート型を使用している場合に応答できるようにしてください。そうでない場合は、あきらめてください。私はそれを把握しようとしているときのようにdynamic_castを示唆するように使用することはできません。どちらの型へのポインタもありません。私は今typeidを調べていて、それが私の問題を解決することを願っていますが、私はまだ別の可能な答えを待っています。

EDIT 2: いくつかの回答をした後、私の要件を満たしているものは何も見つかりませんでした。

基本クラステンプレート:

template<typename FactoryType> 
class Factory 
{ 
public: 
    virtual std::shared_ptr<FactoryType> Create() = 0; 
    virtual ~Factory(){} 
}; 

工場長クラス:ここで一言で言えば要件だ

class Manager 
{ 
    static std::shared_ptr<Manager> singleton; 
public: 
    static std::shared_ptr<Manager> getInstance() 
    { 
     if (!singleton) singleton = shared_ptr<Manager>(new Manager); 
     return singleton; 
    } 
    template<typename FactoryType> 
    Factory<FactoryType>& getFactory() 
    { 
     //Pick a factory here by the type and return it by reference 
     //life cycle is handled by the manager 
    } 
}; 

Managerは、コアの実行可能ファイルの両方で、さまざまなDLLは約知られているであろう。ファクトリの可能な型は、Managerがコンパイルされた時点では認識されず、互いに知り合わないコードによって参照されます。おそらく、おそらく、ここに工場が入っていて、私が知りませんが、それらの多くが他の誰かによって作られていて、dllを入れていることがあります。

+2

C++では先頭のアンダースコア( '_')を使用しないでください。コードが濁ってしまい、多くの場合、言語によって予約されています。 –

+0

文法的な発言:できれば 'unique_ptr'を返し、' shared_ptr'は返せません。前者はコールサイトで後者にバインドすることができます。 –

+2

C++は、.NET言語とは異なり、反射のサポートが非常に貧弱です。あなたの実際のユースケースは何ですか? –

答えて

4

C++ 11を使用しているので、std::type_indexオブジェクトを保存できます。

あなたはtypeidオペレータでそれらを取得:const std::type_info&を返しますが、type_infoは、例えば使用するのに適していないtypeid。地図のキーとして。したがって、その目的のためにstd::type_indexオブジェクトを作成します。実際の解決策はあなた次第です。

std::map<std::type_index, std::shared_ptr<factory>> 

よう

何かは、例えばだろう(あなたのデザインのための正しいポインタ型でshared_ptrを交換してください)。

C++では、実行時の型情報を避けようとしています。あなたが達成しようとしていることを明らかにすれば、より良い解決策を見つけることができます。

class FactoryContainer 
{ 
    struct FactoryConcept { 
     virtual ~FactoryConcept() {} 
     virtual const std::type_info& Type() const; 
    }; 

    template< typename _Ty > struct FactoryModel : FactoryConcept { 
     FactoryModel(const _Ty& t) : factory(t) {} 
     virtual ~FactoryModel() {} 
    private: 
     _Ty factory; 
     const std::type_info& Type() const { return typeid(_Ty); } 
    }; 
    std::shared_ptr<FactoryConcept> factory; 

public: 
    template< typename _Ty > FactoryContainer(const _Ty& _factory) : 
     factory(new FactoryModel<_Ty>(_factory)) {} 

    template <typename T> 
    bool hasType() const { return factory->Type() == typeid(T); } 
}; 

使用方法:(これはあなたのコメントを参照されたい、必要条件であるため)平等のためstd::type_infoオブジェクトを比較提供


EDIT

は、DLLの境界を越えて動作しますが、あなたはこのようにそれを実装することができます:

bool result = container.hasType<double>(); 
+0

私は実際には完全なC++ 11を使用していません。私はmsvC++ 2008を使用していて、usingディレクティブを使用してshared_ptrをstdの名前空間に引き出しています。実際には本当に速いtyping :: tr1 :: shared_ptrを入力しています。私にとって奇妙なことの1つは、完全修飾型の名前を使用するほうがよくないことです。 – lassombra

+0

@lassombra: 'std :: tr1'に' type_index'はありません。msvc10では実装されていないようです。述語として 'before'メンバを使う(あるいは' const std :: type_info * 'sを比較しますが、これはDLL境界を越えて動作しません)、' std :: type_info'の周りに独自のラッパーを設計することを検討できます。 –

+0

これは、DLLの境界を越えてこの分割を行う計画を立てると、厳しい要求です。私は本当にこれをどのように前進させるかわからない。私はプリプロセッサマクロを考慮していましたが、使用可能なファクトリのリストとそれらから構築できるものは動的です。また、リスト全体を保持することも保証できません。他の人がdllを書いています(これは部分的にプラグインシステムと組み合わせて使用​​されています) – lassombra

0

これは既に存在します。これは、dynamic_cast<T*>(ptr)と呼ばれ、それが真を返す場合ptrTにポイントまたは*ptrT両方の静的型は、少なくとも1つの仮想機能を有していると仮定しTに由来する任意のクラス。

実行時にtypeid()と関連する友人を使用してタイプに関する情報を検出することもできます。

+0

'dynamic_cast'は本当に_true_ ...;)を返しません。 – Fiktik

+1

^実際それは決してありません:D;ブール値に暗黙的にキャストすることができます。 –

関連する問題