使用类列表C ++的虚方法

时间:2014-03-12 13:43:08

标签: c++ list inheritance

首先,请原谅我的英语不好。

我正在尝试使用继承在c ++中实现检查器,为此我设置了基类piece和2个派生类pawnqueen

我使用了班级列表中的两个列表,每个玩家一个,第一个版本(仅限典当),它运行良好。

但现在我将pawn列表更改为piece列表,我遇到了一些问题。

我调用pawn构造函数,因此对象是pawn,但是当我调用一个方法(在piece类中是虚拟的)时,它会调用piece方法!

这就是我所拥有的:

piece.hpp:

virtual int calculardestino(int,tablero*){ cout <<"Not here" << endl;};

pawn.cpp:

int peon::calculardestino(int dir,tablero* B){ cout <<"Yep here is ok" << endl;}

我使用以下方法设置典当列表:

listarojo.push_back(peon(i,j,1));

我尝试以这种方式调用方法:

pos=listarojo.begin();
pos->calculardestino(0,this);

但我永远不会"Yep here is ok",只有"Not here"

我试图让它变成纯虚拟但我在编译时遇到错误。

再次,抱歉我的英语不好。

2 个答案:

答案 0 :(得分:1)

您需要使用指针列表到piece个对象(而不是piece个对象列表):

list<piece*> listarojo;
listarojo.push_back(new peon(i,j,1));

您必须在程序执行的稍后时间删除这些对象:

for (auto ptr=listarojo.begin(); ptr!=listarojo.end(); ptr++)
    delete *ptr;

答案 1 :(得分:0)

看起来listarojopiece个对象的容器;所以推送pawn切片,将其转换为基类类型。

对于多态性,它必须包含指向piece的指针,您必须使用new分配指针,或者存储在列表生命周期内持续存在的地方。如果您选择使用new,那么您可能希望将它们设为智能指针,以避免记住删除它们的麻烦。

您可以通过使基类 abstract 来防止切片,从而无法直接实例化它。不要提供像calculardestino这样的函数的虚拟实现,而是考虑使它们纯虚拟

virtual int calculardestino(int,tablero*) = 0;
  

我试图让它变成纯虚拟但我在编译时遇到错误。

实际上,这个错误就是你想要的:切片被阻止了,所以你得到一个友好的错误,而不是意外的运行时行为。通过存储指针而不是piece对象来修复底层问题,将解决该错误。