首先,请原谅我的英语不好。
我正在尝试使用继承在c ++中实现检查器,为此我设置了基类piece
和2个派生类pawn
和queen
。
我使用了班级列表中的两个列表,每个玩家一个,第一个版本(仅限典当),它运行良好。
但现在我将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"
。
我试图让它变成纯虚拟但我在编译时遇到错误。
再次,抱歉我的英语不好。
答案 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)
看起来listarojo
是piece
个对象的容器;所以推送pawn
将切片,将其转换为基类类型。
对于多态性,它必须包含指向piece
的指针,您必须使用new
分配指针,或者存储在列表生命周期内持续存在的地方。如果您选择使用new
,那么您可能希望将它们设为智能指针,以避免记住删除它们的麻烦。
您可以通过使基类 abstract 来防止切片,从而无法直接实例化它。不要提供像calculardestino
这样的函数的虚拟实现,而是考虑使它们纯虚拟:
virtual int calculardestino(int,tablero*) = 0;
我试图让它变成纯虚拟但我在编译时遇到错误。
实际上,这个错误就是你想要的:切片被阻止了,所以你得到一个友好的错误,而不是意外的运行时行为。通过存储指针而不是piece
对象来修复底层问题,将解决该错误。