如何构建程序以避免查询对象类型?

时间:2017-07-01 06:35:38

标签: c++ chess

我是编程新手,作为我的第一个没有指导教程的项目之一,我正在实施国际象棋程序。我现在的结构方式是,有一个名为Piece的基类,每种类都派生自该基类。这样,我可以将板实现为Pieces的二维数组,基类表示空方块。这一点运作良好,直到我考虑到我需要做些什么才能确定国王是否在检查中。这样做对我来说最不浪费的方法是给国王阶级一个功能,例如,检查国王是否与任何敌人的车或主教有视线,检查两个中的任何一个是否有敌人的棋子他们可以到达国王等的方块。但要做到这一点,函数需要知道哪些特定的派生类在哪里。我想我可以通过给每个片段类一个ID成员来检查它的功能来使它工作,但这似乎是多余的,而且,我认为需要这些信息的程序被认为结构很糟糕。到目前为止,我实际上做出了一个糟糕的选择,如果是的话,我该如何清理呢?

道歉,这不是一个非常笼统的问题。我无法想出一种对我来说有用的方法。

2 个答案:

答案 0 :(得分:0)

它可能不是最优雅或最安全的。这样做的方式。

如果该棋子是王者,你可以使用reinterpret_cast(King*)将指针投射到国王班的指针,然后调用属于它的方法。

这样你就不必为每一件都实现它。

示例:

class Base
{
public:
    unsigned int id;
    virtual Base() { id = 0 }
};

class Child1 : public Base
{
public:
    virtual Child1() { id = 1; }
};

class Child2 : public Base
{
public:
    virtual Child2() { id = 2; }

    // implement the check, checking here.
    void Child2SpecificMethod() { id++; }
};

int main()
{
    Base& test1=Child1();
    Base& test2=Child2();

    // convert tests to pointers and attempt to call the "Child2SpecificMethod"
    ((Child1*)&test1)->Child2SpecificMethod(); // Won't work
    ((Child2*)&test2)->Child2SpecificMethod(); // Will work

    return 0;
}

这是非常c风格的,应该可以使用但我无法测试,因为我现在正在使用我的手机。

答案 1 :(得分:0)

从我的描述中我可以收集到的内容,polymorphism似乎就像你正在寻找的那样

int abs(int x) { return x < 0 ? -x : x; }

class Piece
{
public:
    Piece(int x, int y) : x{x}, y{y} {}
    virtual bool reachable(const Piece&) const = 0;

    // other methods

protected:
    int x, y;
    std::pair<int, int> delta(const Piece& p) const
    {
        return {abs(x - p.x), abs(y - p.y)};
    }
};

class Knight : public Piece
{
public:
    using Piece::Piece;
    bool reachable(const Piece& p) const override
    {
        auto [dx, dy] = delta(p);
        if((dx == 1 && dy == 2) || (dx == 2 && dy == 1))
            return true;
        return false;
    }
};

class King : public Piece
{
public:
    using Piece::Piece;
    bool reachable(const Piece& p) const override
    {
        auto [dx, dy] = delta(p);
        if(dx <= 1 && dy <= 1)
            return true;
        return false;
    }
};

// other pieces

class Board
{
public:
    bool check(const King& k) const
    {
        for(auto& p : pieces)
            if(p->reachable(k))
                return true;
        return false;
    }
private:
    std::vector<std::unique_ptr<Piece>> pieces;
};

Piece有一些常见的界面,包括reachable,表示该作品是否可以到达指定的部分。

要检查是否有支票,请重复收集件,看看他们是否可以到达指定的国王。