2015-01-20 32 views
0

我有一個名爲「block」的類,它從名爲「MainObject」的類繼承。調用列表中的子對象

然後我創建了一個列表並添加「塊」。我也使用迭代器來循環;

std::list<MainObject> objList; 

objList.push_back(block()); 
std::list<MainObject>::iterator p = objList.begin(); 

但是當我循環思考列表我只能調用MainObject的函數。 這是我的循環

for (p = objList.begin(); p != objList.end(); p++){ 
     p->Update(); 
} 
+0

當你迭代你的'objList'時,你怎麼知道你是在處理一個'block'還是'MainObject'?如果你想要一個塊列表,爲什麼不聲明你的列表? 'std :: list '。你需要提供更多的上下文。 – Julian 2015-01-20 19:26:44

+0

這是因爲我想添加更多的對象類型到列表中。所有對象都有一個Update函數,必須在每一幀都調用它。 – SaschaDeWaal 2015-01-20 19:39:16

+0

馬特的回答下面應該做你需要的。有了最近評論中的額外信息,請注意,如果'MainObject'具有** virtual **'Update'方法,則不再需要強制轉換,並且只需執行'p-> Update()'。 – Julian 2015-01-20 19:50:22

回答

2

您使用的是存儲在列表中,而不是繼承「塊」對象acctual MainObject。你應該使用基本指針:

 std::list<MainObject* > objList; 

     objList.push_back(new block()); 
     for (p = objList.begin(); p != objList.end(); p++){ 
      block* b = dynamic_cast<block*>(p); 
      if (b) 
      b->Update(); 
} 

如果使用std::list<MainObject>objList.push_back將創建輸入參數的副本,並存儲MainObject,不那麼繼承類型,這就是爲什麼你只能叫MainObject的功能。

但是,當列表存儲基類的指針時,它應該只調用基類的函數。將其轉換爲子類型並調用子類型的功能並不是一個好設計。基類就像一個合同,這種行爲打破了合同。

+0

如果'* p'不是'block'的實例會發生什麼? – Julian 2015-01-20 19:32:41

+0

@ AtlasC1,好點。更新了我的答案。 – Matt 2015-01-20 19:40:37

+0

好東西; +1! – Julian 2015-01-20 19:43:07