添加一个方法后类的奇怪行为

时间:2013-06-06 18:48:57

标签: c++

所以我正在用C ++编写简单的控制台战舰。我有一个像这样的船类:

class Ship {
    public:
        virtual void draw(int x, int y){}
        virtual void shoot(int x, int y){}
        virtual bool isDead(){};
};

和从它继承的两个类(水平和垂直船)。因此,垂直样本是:

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;
        }
};

所以我的牌组中的每个单元格都在对象内部表示。当有人在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;
}

一旦我取消注释if,奇怪的行为就会开始。它给了我不正确的信息(声称其中有船的单元格是空的,反之亦然)并且游戏在三次射击后崩溃。但是,如果我对它进行评论,它的效果非常好 - 如果你完全沉没一艘船,就不会让你知道。

它出了什么问题?如果我在这个做恶意的话吗?遗憾的是,我无法提供一个简短的,可编辑的来源,因为如果没有大多数类和方法,这个游戏根本就不会运行,而且还有很多。

2 个答案:

答案 0 :(得分:5)

如果您只是取消注释,则语义会发生变化:

目前是:

void Board::fire(int w, int k)
{
    if(mapOfCells[w][k]>=0)
        ships[mapOfCells[w][k]]->traf(w,k);
    else
        mapOfCells[w][k]=-2;
}

如果您取消注释,它将变为:

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;
}

不确定这是否有意。你的意外行为可能来自于此,因为你的缩进看起来像你想要的东西。如上所述,您的默认实现也缺少一个返回值,它应该为您提供编译器警告和未定义的结果。

答案 1 :(得分:4)

尝试在if子句周围加上大括号。您的else子句绑定到第二个if语句而不是第一个,并且您的第二个if语句正在无条件执行。