2011-08-03 5 views
2

なし継承したクラスのいずれかの方法で、私はいくつかのベースclass A、および継承したクラスをいくつか持っている:コールそれらの仮想プロトタイプ

class B : public A 
class C : public A 
class D : public A 

を私は設定呼び出しで名前を使用し、いくつかの設定ファイルを解析して機能を、持っています

void do_smth<B>(...); 
void do_smth<C>(...); 
void do_smth<D>(...); 

私はmap<A*> objs;を持っており、それらの機能に起こった:

void do_smth<T>(...) 
{ 
    T *control = new T(); 
    ... 
    objs[name] = T; 
} 

私はポインタのマップを持っているので、私はnameを得て、B、CまたはDクラスに値を格納する必要があります。 ()、C - text()、D - currentValue()関数を持っているので、これらの値を返すクラスに仮想関数を追加できないという問題があります。私は、value(), text(), currentValue()の結果をクラスに応じて返す関数get_value()が必要ですか? 問題を解決するために私に助言してもらえますか?

私は2つの方法を参照してください。

1)私は、クラスB、C、Dへのポインタから関数を記述し、そのget_value((B*)objs[name]);のような関数を呼び出すが、私は、それはよくないことだと思うことができます。

2)作成するB、C、D変数に関数が必要なオブジェクトboost::bindを作成できます。

どのようにすればよいでしょうか、それとも良いことを教えてください。

+0

コントロールには、 'value()'、 'text()'、 'currentValue()'のようなメソッドがあります。 –

+0

純粋なQTではない - これらのライブラリのいくつかの拡張 – Olympian

+1

これらのクラスがQtメタシステム(MOC、Q_OBJECTなど)を使用する場合は、 'QObject :: metaObject()'と 'QObject :: inherits()'を使ってあなたが実際に持っているクラスと 'qobject_cast()'をこのクラスにアップキャストして、適切なvalueメソッドにアクセスします。 –

答えて

3

ですから、

A* a; 

を持っており、それが何であるかの種類を知りません。試してみてくださいdynamic_cast

B* b = dynamic_cast<B*>(a); 
if (b) 
    return b->value(); 
//C and D the same way 
+0

Thx Ferdinand、それは私が言ったことです。 :) –

+0

"このコードの第2の変換では、基底クラスがポリモーフィックでない限り、基底から派生した変換はdynamic_castで許可されないため、コンパイルエラーが発生します。 dynamic_case <>についてはcplusplus.comからの引用です。 「基本クラスが多態的になるまで」という意味を説明できますか?どのような基準ですか? – Olympian

+0

つまり、基本クラスAには仮想メソッドがありません。 static_castがこの場合に動作するかどうかはわかりませんが、試してみてください。 –

0

あなたはタイプ形質を使用できます。各クラスの "識別子"(例:列挙値)を導出するために、クラスB、C、Dのそれぞれの型特性を作成します。この識別子をobjs配列に格納します。後で、この識別子をswitch-caseでどのクラスにobjの各要素をキャストするかを調べることができます。あなたが必要な場合があります仮想どんな機能を追加することができ、クラスXに

class A{}; 
class B : public A{}; 
class C : public A{}; 
class D : public A{}; 

enum ClassType {B_type, C_type, D_type, Unknown_type}; 

template<typename T> 
struct Identifier{static const ClassType value = Unknown_type;}; 

template<> 
struct Identifier<B>{static const ClassType value = B_type;}; 

template<> 
struct Identifier<C>{static const ClassType value = C_type;}; 

template<> 
struct Identifier<D>{static const ClassType value = D_type;}; 


template<typename T> 
void do_smth() 
{ 
    T *control = new T(); 
    ... 
    objs[name] = control; 
    ids[name] = Identifier<T>::value; 
} 

void test() 
{ 
    do_smth<X>(); // X is of type B, C, D 

    ... 

    switch (ids[name]) 
    { 
    case B_type: 
     { 
      B* b = static_cast<B*>(objs[name]); 
      // do something with b 
      break; 
     } 
    case C_type: 
     { 
      C* c = static_cast<C*>(objs[name]); 
      // do something with c 
      break; 
     } 
    case D_type: 
     { 
      D* d = static_cast<D*>(objs[name]); 
      // do something with d 
      break; 
     } 
    default: 
     ;//error 
    };  
} 
0

継承A。

次に、B、C、DからXを継承し、多型にX *を使用します。

関連する問題