如何构建我的程序以避免查询对象类型?
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
,表示棋子是否能到达指定的棋子
检查是否有对子,遍历棋子集合,看是否能到达指定的王。
我是编程新手,作为我第一个没有教程指导的项目之一,我正在实现一个国际象棋程序。我现在的结构方式是,有一个名为 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
,表示棋子是否能到达指定的棋子
检查是否有对子,遍历棋子集合,看是否能到达指定的王。