2011-03-05 56 views
6

簡短說明:
我遍歷向量調用向量中的每個對象上的虛擬函數,以執行一系列操作。向量是迭代器的基類。所有的物體都是兒童。當虛函數被調用時,它執行基類的函數。虛擬函數:遍歷向量填充子類對象的向量<Base Class>

(真的)長的描述: 我試圖擁有一組行爲的生物模型。我的基類是抽象的,只有兩個,所有的子類都重寫功能(虛擬):

class Behavior 
{ 
public: 
    Behavior(); 
    ~Behavior(void){} 
virtual void execute(){} 
virtual BEHAVIOR_TYPE getType() {return m_Type;} 


protected: 
BEHAVIOR_TYPE m_Type; 
}; 

我創造了許多兒童的行爲,如移動,消耗,偵察等

class Move : 
    public Behavior 
{ 
public: 
BEHAVIOR_TYPE getType() {return m_Type;} 
    enum Direction {N, NE, E, SE, S, SW, W, NW}; 
Move(DOCO * d); 
~Move(void); 
void execute() ; 
    Direction chooseDirection(); 
    void setDirection(Direction newDirection); 
private: 
    Direction m_Direction; 
    DOCO *I; 
BEHAVIOR_TYPE m_Type; 

}; 

我創建了一個矢量到其上我推各行爲子類的實例,以及一個迭代遍歷它:

vector<Behavior> m_Behavior; 
vector<Behavior>::iterator bIt; 

當生物得的動作序列,我嘗試所迭代e遍歷向量,解引用迭代器,並調用執行函數:

void World::justDoIt() 
{ 
    for(dIt=myDOCO.begin(); dIt!=myDOCO.end(); ++dIt) 
{ 
    vector<Behavior>::iterator myBehavior=(dIt)->getFirstBehavior(); 
    vector<Behavior>::iterator end=(dIt)->getLastBehavior(); 
    for(myBehavior; myBehavior!=end; ++myBehavior) 

     (*myBehavior).execute(); 
} 
} 

問題是它執行父級的函數而不是子級的函數。

在我對後期綁定的理解中,它應該根據調用它的對象的類型自動調用適當的函數,而不是調用它的指針的類型,並且在我的代碼中,我預計它將指向孩子的對象。

很顯然,我已經犯了一個錯誤,並以某種方式告訴我,我想,這些被作爲父母,而不是孩子的治療方案,但我找不到我的錯誤。

第二個現象是,它不會讓我父母起作用​​的純虛擬的,因爲它說,它無法實例化一個抽象類。我沒有在我的代碼中的任何地方明確地實例化它,但是必須有某個地方我隱式地做它。但是,我無法找到哪裏。當然,建立一個向量來保存父類的對象,不需要實例化父,那就是我直接引用父類中唯一的一次。

任何幫助將不勝感激。

+0

有應該是幾十個受騙者爲把基類_objects_(而不是_pointers_)成STL容器,雖然我不能,ATM,找到一個。其中一個應該可能成爲[FAQ條目](http://stackoverflow.com/questions/tagged/c%2b%2b-faq)。 – sbi 2011-03-05 00:20:07

回答

10

vector<Behavior>使用複製構造函數Behavior::Behavior(const Behavior&);將您存儲在其中的任何內容進行復制。這破壞了多態性。你需要使用一個指針或智能指針容器代替:

vector<Behavior*> m_Behavior; // I will take care of new and delete 
vector<shared_ptr<Behavior> > m_Behavior; // easier 

如果你沒有std::shared_ptrstd::tr1::shared_ptr#include <memory>或相似的呢,也許你可以使用Boost的。

+0

非常感謝!我不知道共享指針! – Sisyphus 2011-03-05 00:32:43

+2

如果你有'std :: shared_ptr',那麼在這裏使用'std :: unique_ptr'。 – 2011-03-05 11:14:40

4

您要添加實例類矢量。這導致slicing

你需要做的就是添加指針到行爲的情況下,並修改循環來

(*myBehavior)->execute(); 
+0

非常感謝! – Sisyphus 2011-03-05 00:31:41