如何迭代定义为超类的向量,但调用子类方法
C++ How to iterate over a vector defined as a super class, but call sub class methods?
我有Java背景,我正试图理解c++中的多态性。具体来说,就是如何在std vector中的一系列子类(由它们的超类定义)上迭代,以便调用特定的方法。我想做的是让子类重写将要调用的超类方法。然而,我不确定如何在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的另一个子类。我做错了什么或者遗漏了什么?提前感谢!
您需要一个Tile*
的向量,或者更好的是std::unique_ptr<Tile>
;
你应该用指向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次。
相反,如果您定义vector来包含基类Tile的实例,那么存储在vector中的对象将被拼接,即使它们最初是作为派生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
这将打印Drawing Tile 3次,假设:
void Tile::drawTile() { std::cout << "Drawing Tile" << std::endl; }
在拼接中发生的事情是,只有Tile_Grass的基对象部分被复制到向量元素中,因为您声明希望向量包含该基对象的实例。
相关文章:
- 变量没有改变?通过向量的函数调用
- 在c++中使用向量时,如何调用构造函数和析构函数
- 我使用向量来创建类对象列表.初始化向量时如何使用参数调用构造函数?
- 向量推回调用析构函数时调用析构函数
- 在具有向量的类构造函数中进行析构函数调用
- 使用并行参数向量调用元素向量的成员函数
- 在 c++ 中,如何使用向量调用派生类?
- 使用参数向量调用函数
- 从向量C 调用播放器统计信息
- C++ 向量:调用push_back时出错
- 在C++中,何时自动为本地向量调用析构函数
- 对shared_ptr的向量调用clear().内存会被释放吗
- 对向量调用.end()的复杂性是多少
- 从指针向量调用函数
- 对存储在boost::any中的向量调用vector::size()
- 试图使用指向函数的指针向量调用函数,但未能返回正确的值——这是我的编译器吗
- 在函数定义为main的类中,从函数指针的向量调用函数
- 为什么空向量调用值类型的默认构造函数?
- 从基类对象的指针向量调用派生类的唯一函数
- 从抽象类的指针向量调用函数