我有Java背景,我正在尝试理解C ++中的多态性。具体来说,如何迭代由超类定义的std向量中的一系列子类,以便调用特定方法。我想要做的是让子类覆盖将被调用的超类方法。但是,我不知道如何在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
}
现在for循环只调用“Tile :: drawTile()”,但我想让它调用“Tile_Grass :: drawTile()”,或者是“tileVector”向量中的Tile的另一个子类。我做错了什么或错过了什么?提前谢谢!
答案 0 :(得分:4)
你需要一个Tile*
的矢量,或者更好的是,std::unique_ptr<Tile>
;
答案 1 :(得分:3)
您应该使用指向Tile的指针声明并填充您的tileVector,而不是Tile对象的副本。
这是一个完整的Visual Studio 2012示例项目:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <memory>
class Tile {
public:
virtual void drawTile();
};
void Tile::drawTile() {}
class Tile_Grass : public Tile {
public:
void drawTile();
};
void Tile_Grass::drawTile() { std::cout << "Drawing Tile Grass" << std::endl; }
int _tmain(int argc, _TCHAR* argv[])
{
typedef std::vector<std::unique_ptr<Tile>> TileVector;
TileVector vec;
// add a few Tile_Grass objects
vec.push_back(std::unique_ptr<Tile>(new Tile_Grass()));
vec.push_back(std::unique_ptr<Tile>(new Tile_Grass()));
vec.push_back(std::unique_ptr<Tile>(new Tile_Grass()));
for (auto itr = vec.begin(); itr != vec.end(); ++itr) {
(*itr)->drawTile(); // draws Tile_Grass, or any other sub class of Tile, but NOT Tile
}
return 0;
}
这将输出 Drawing Tile Grass 3次。
相反,如果您将矢量定义为包含基类Tile的实例,则存储在矢量中的对象将拼接,即使它们最初是作为派生的Tile_Grass对象创建的:< / p>
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_Grass的基础对象部分被复制到向量元素中,因为您声明要包含该基础对象实例的向量。