使用类列表的虚方法

Virtual methods using class list C++

本文关键字:方法 列表      更新时间:2023-10-16

首先,请原谅我的英语很差。

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

我从职业列表中使用了两个列表,每个玩家一个,在第一个版本中(只有小兵)它运行得很好。

但现在我把pawn列表改为piece列表,我有一些问题。

我调用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"

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

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

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

并且你必须在程序执行的稍后时刻删除这些对象:

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

看起来listarojopiece对象的容器;因此,按下pawn切片,将其转换为基类类型。

对于多态性,它必须包含指向piece的指针,您必须与new一起分配,或者存储在列表生命周期中持续存在的地方。如果您选择使用new,那么您可能想让它们成为智能指针,以节省记住删除它们的麻烦。

你可以通过使基类抽象来防止切片,这样它就不能被直接实例化。与其提供像calculardestino这样的函数的虚拟实现,不如考虑让它们成为纯虚拟的:
virtual int calculardestino(int,tablero*) = 0;

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

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