所以我正在用C++编写简单的控制台战舰.我有一个像这样的船类:
class Ship {
public:
virtual void draw(int x, int y){}
virtual void shoot(int x, int y){}
virtual bool isDead(){};
};
Run Code Online (Sandbox Code Playgroud)
和两个继承它的类(水平和垂直船).所以垂直样本是:
class VertShip : public Ship{
private:
int x, y, shipSize;
char deck[4];
public:
VertShip(int x, int y, int shipSize) : x(x), y(y), shipSize(shipSize) {
for(int i=0; i<shipSize; ++i)
{
deck[i] = '_';
}
}
virtual void draw(int x, int y){
cout << deck[y - this->y];
}
virtual void shoot(int x, int y){
deck[y - this->y] = 'T';
--shipSize;
}
virtual bool isDead()
{
if(this->shipSize) return 0;
return 1;
}
};
Run Code Online (Sandbox Code Playgroud)
所以我的牌组中的每个单元都表示在对象内部.当有人在Board类上调用fire()方法并成功击中船只时,Shoot()会运行,而draw()会提供有关船舶甲板上给定单元格的drawBoard()方法信息.此外,ships []是指向船舶对象的指针数组.所以到目前为止一切正常 - 问题在于Board :: fire():
void Board::fire(int w, int k){
if(mapOfCells[w][k]>=0)
ships[mapOfCells[w][k]]->shoot(w,k);
//if(ships[mapOfCells[w][k]]->isDead()) cout<<"The ship has drown.\n";
else
mapOfCells[w][k]=-2;
}
Run Code Online (Sandbox Code Playgroud)
一旦我取消注释if,奇怪的行为就会开始.它给了我不正确的信息(声称其中有船的单元格是空的,反之亦然)并且游戏在三次射击后崩溃.但是,如果我对它进行评论,它的效果非常好 - 如果你完全沉没一艘船,就不会让你知道.
它出什么问题了?如果我在这个做恶意的话吗?遗憾的是,我无法提供一个简短的,可编辑的源代码,因为如果没有大多数类和方法,这个游戏根本就不会运行,并且它们中有相当多.
如果您只是取消注释,那么语义会发生变化:
目前它是:
void Board::fire(int w, int k)
{
if(mapOfCells[w][k]>=0)
ships[mapOfCells[w][k]]->traf(w,k);
else
mapOfCells[w][k]=-2;
}
Run Code Online (Sandbox Code Playgroud)
如果你取消注释,它会变成:
void Board::fire(int w, int k)
{
if(mapOfCells[w][k]>=0)
ships[mapOfCells[w][k]]->traf(w,k);
if(ships[mapOfCells[w][k]]->isDead())
cout<<"The ship has drown.\n";
else
mapOfCells[w][k]=-2;
}
Run Code Online (Sandbox Code Playgroud)
不确定这是否有意.你的意外行为可能来自于此,因为你的缩进看起来像你想要的其他东西.如上所述,您的默认实现也缺少一个返回值,它应该为您提供编译器警告和未定义的结果.