2014-03-12 20 views
-3

首先,请原谅我的英文不好。使用类列表C++的虚拟方法

我想在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"

我试图让它变成纯虚拟的,但是我在编译时出错。

再次,对不起我的英语不好。

+1

你可以发布你的类的代码(头+实现)吗? –

+0

您是否尝试过[使用调试器](http://www.youtube.com/watch?v=eEJ5xKO7c3o)? – sashoalm

回答

0

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

对于多态性,它将不得不包含指向piece的指针,您必须使用指向new的指针,或者存储某个在列表生存期内保持不变的地方。如果您选择使用new,那么您可能希望使它们成为智能指针,以节省记住删除它们的麻烦。

您可以通过使基类抽象来防止切片,以便它不能直接实例化。而不是提供一个虚拟实现的功能,如calculardestino,可以考虑让他们纯虚

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

我试图使它的纯虚拟的,但我得到的编译错误。

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

+0

非常感谢大家。我了解问题所在,并且可以正确解决问题。 – user3055867

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;