2013-06-19 97 views
2

我有一個Java背景,我想了解C++中的多態。具體而言,如何迭代由超類定義的std向量中的一系列子類,以便調用特定的方法。我想要做的是讓子類重寫將要調用的超類方法。但是,我不確定如何在C++中執行此操作。C++如何遍歷定義爲超類的向量,但調用子類方法?

下面是一些代碼,以幫助快速性:

class Tile { 
    public: 
      virtual void drawTile(); 
    } 

    void Tile::drawTile() {} // not sure if this is needed? 

    class Tile_Grass : public Tile { 
    public: 
      void drawTile(); 
    } 

    void Tile_Grass::drawTile() { ... do stuff ... } 

我想要做的是:

using namespace std; 
    for (vector<Tile>::iterator itr = tileVector.begin(); itr != tileVector.end(); ++itr) { 
      itr->drawTile(); // draws Tile_Grass, or any other sub class of Tile, but NOT Tile 
    } 

眼下對於僅環所謂的 「瓦:: drawTile()」,但我希望它叫「Tile_Grass :: drawTile()」,或者是「tileVector」向量中Tile的另一個子類。我做錯了什麼或失蹤?提前致謝!

回答

4

你會想要一個向量Tile*,或者,更好的,std::unique_ptr<Tile>;

3

您應該使用指向Tile的指針聲明並填充tileVector,而不是Tile對象的副本。

下面是一個完整的Visual Studio 2012示例項目:

這將輸出繪圖瓷磚草 3倍。

相反,如果你定義矢量包含基類瓷磚的實例,存儲在矢量對象將是拼接,即使他們最初是作爲衍生Tile_Grass對象創建:

typedef std::vector<Tile> TileValueVector; 

TileValueVector vecv; 

// add a few Tile_Grass objects 
vecv.push_back(Tile_Grass()); 
vecv.push_back(Tile_Grass()); 
vecv.push_back(Tile_Grass()); 

for (auto itr = vecv.begin(); itr != vecv.end(); ++itr) 
    itr->drawTile(); // draws Tile 

這將打印製圖磁磚 3倍,假設:

void Tile::drawTile() { std::cout << "Drawing Tile" << std::endl; } 

在剪接發生的是,只有Tile_G的基礎對象部由於您聲明您想要包含該基礎對象實例的向量,因此rass會被複制到向量元素中。