2016-12-28 194 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