【发布时间】:2016-06-08 20:17:25
【问题描述】:
我想创建一个函数“void set_tic_tac_toe_start_player(char c)”。这不是函数的实际名称,但它解释了它的意图。
之所以要在编译时完成,是因为我想创建一个类来封装井字游戏系统,这样系统就可以在游戏开始前显式覆盖start player,而无需重新构建类。
这是一个简单复杂的示例代码。
#include <iostream>
#include <cstdlib>
class TTCSystem
{
public:
static const int PLAYERX = 1;
static const int PLAYERO = 2;
void set_tic_tac_toe_start_player(char c);
private:
int start_player;
};
void TTCSystem::set_tic_tac_toe_start_player(char c)
{
if (c == 'x' || c == 'X') {
this->start_player = PLAYERX;
} else if (c == 'o' || c == 'O') {
this->start_player = PLAYERO;
} else {
std::cout << "PANICING AS HARD AS I CAN" << std::endl;
exit(0);
}
}
int main(int argc, char **argv)
{
TTCSystem ttcs;
ttcs.set_tic_tac_toe_start_player('9');
return 0;
}
该函数用于覆盖默认进入井字游戏的玩家'X'或'O'。
问题是任何字符都可以通过,而只想接受 {'x', 'X', 'o', 'O'}。
我可以创建一个枚举,但恐怕枚举不会强制进行类型检查。
我可以使用一个类来发明一个枚举类型,或者利用继承,但即使我走这条路,我也不想重新发明轮子并在这方面做得很糟糕。
是否有更通用/优雅/简单的解决方案来创建类型安全的枚举?
我正在寻找能够确保在编译时检查 set_tic_tac_toe_start_player 的输入以确保选择首先进入的玩家是有效玩家(4 个输入之一)。
[编辑]感谢乔纳森的建议,我已经在下面发布了解决方案。
【问题讨论】:
-
为什么要在编译时检查?你从不在运行时使用这个函数?
-
你说得有道理。我可以将其设置为常量,我只是想要一个干净的程序员的覆盖。让我重新表述一下这个问题。
-
我添加了一个简单的小代码来展示我想要做什么的总体思路。这不是最干净的独立演示,但我认为它有点道理。 @Shumush 我在编译时检查,以便我提供一个简单的程序员界面来操作井字游戏系统,而无需重建类。
-
class TTCSystem { enum Player { PlayerX, PlayerY }; void set_tic_tac_toe_start_player(Player p) { start_player = p; } ... };有什么问题?枚举类型的唯一有效值是PlayerX和PlayerY(即 0 和 1)。任何其他值都超出了该类型的值范围。在任何情况下,您都可以使用if (start_player == PlayerX) ... else ...,以便将任何非零值视为PlayerY -
如果你想要类型安全的枚举,为什么不使用类型安全的枚举?
标签: c++ type-safety