2016-12-28 4 views
-2

共通の祖先を継承するクラスのリストを反復処理できるようにしたいと考えています。クラスのリストを反復する

(それは私がから来ている言語だとしてPythonのような構文)私が何をしたいの縮小さバージョン:

const *Player *PLAYERS[3] = { *PlayerTypeOne, *PlayerTypeTwo, *PlayerTypeThree}; 

int outcome = 0; 

for player in players { 
    if (doThingWithPlayer((&player)(), some, other, variables) == true) { 
     outcome++; 
    } 
} 

これは操作のこの種を行うための好ましい方法ではない場合、方法についてのアドバイス私は続けなければならないのは大歓迎です。

私は避けたいコードの種類は次のとおりです。

int outcome = 0; 

PlayerTypeOne player_one(); 
if doThingWithPlayer(player_one, some, other, variables){ 
    outcome++; 
} 
PlayerTypeTwo player_two(); 
if doThingWithPlayer(player_two, some, other, variables){ 
    outcome++; 
} 
PlayerTypeThree player_three(); 
if doThingWithPlayer(player_three, some, other, variables){ 
    outcome++; 
} 
+0

クラスのリストやクラスインスタンス(すなわち、オブジェクト)のリスト:あなたが何ができるか

は使用メタプログラミングのですか? – NPE

+1

'object'と' class'という用語を混在させますか? –

+0

@NPEクラスのリスト – muddyfish

答えて

1

あなたはfactory design patternを探しています:

Player *create_by_name(const std::string &what) 
{ 
    if (what == "PlayerTypeOne") 
     return new PlayerTypeOne; 
    if (what == "PlayerTypeTwo") 
     return new PlayerTypeTwo; 

    // ... 
} 

のように。また、各サブクラスのコンストラクタにパラメータを渡すこともできます。

すべてのサブクラスが同じコンストラクタパラメータを使用する場合、これは簡単になります。パラメータをファクトリに渡し、コンストラクタに渡します。

コンストラクタに異なるパラメータをサポートする必要がある場合、これはより複雑になります。私は小さなものから始め、オブジェクトのための単純なファクトリを実装することをお勧めします。コンストラクタパラメータはなく、すべてのサブクラスで同じものがいくつかあります。基本的な原則が働いたら、複雑なコーナーケースを処理することを心配することができます。

次に、クラス名の配列を持ち、配列を繰り返し処理し、ファクトリを呼び出します。これは、擬似Pythonコードと似た結果になります。

+4

生ポインタ:( –

1

C++には組み込みのイントロスペクションが用意されていないため、クラスを表すオブジェクトを取得したり、インスタンスを作成することはできません。

// A list of types 
template <class...> struct pack { }; 

// Calls f with one default-constructed instance of each T 
template <class... Ts, class F> 
void construct_each(pack<Ts...>, F &&f) { 

    // Classic pre-C++17 expansion trick 
    using ex = int[]; 
    (void)ex{(f(Ts{}), void(), 0)..., 0}; 

    // C++17 version 
    // (void)(f(Ts{}), ...); 
} 

// ... 

using Players = pack<PlayerTypeOne, PlayerTypeTwo, PlayerTypeThree>; 

void foo() { 
    int outcome = 0; 

    construct_each(Players{}, [&](auto &&player) { 
     if(doThingWithPlayer(player, some, other, variables)) 
      ++outcome; 
    }); 
} 

See it live on Coliru