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

How do I structure my program to avoid having to query for the types of objects?

我是编程新手,作为我第一个没有教程指导的项目之一,我正在实现一个国际象棋程序。我现在的结构方式是,有一个名为 Piece 的基础 class,每种类型的片段都源自该基础 class。这样,我就可以将棋盘实现为一个二维 Pieces 数组,底数 class 代表空方块。在我考虑我需要做什么来确定国王是否处于检查状态之前,这一直很有效。对我来说最不浪费的方法是给国王 class 一个功能,例如,检查国王是否与任何敌方车或主教有视线,检查是否有敌方兵他们可以到达国王的两个方格中的任何一个,等等。但是要做到这一点,函数需要知道哪个特定的派生 classes 在哪里。我想我可以通过给每个片段 class 一个 ID 成员来让函数检查来让它工作,但这似乎是多余的,此外,我认为需要此类信息的程序被认为是结构错误的。到目前为止,我是否真的做出了错误的选择?如果是,我该如何改正?

抱歉,这不是一个非常笼统的问题。我想不出一种概括它的方法仍然对我有帮助。

这可能不是最优雅或 'safe' 的实现方式。

如果棋子是国王,你可以使用reinterpret_cast(King*)将它的指针转换为国王class的指针,然后调用属于的方法它。

这样你就不必为每件作品都实施它。

示例:

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 风格的,应该可以工作,但我无法测试它,因为我现在正在使用我的 phone。

根据我从您的描述中了解到的信息,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,表示棋子是否能到达指定的棋子

检查是否有对子,遍历棋子集合,看是否能到达指定的王。