如何干净地创建类型安全的枚举参数



我想创建一个函数"void set_tic_tac_toe_start_player(char c)"。这不是函数的实际名称,但它解释了它的意图。

我希望在编译时完成此操作的原因是,我想创建一个类来封装 TicTacToe 系统,以便系统可以在游戏开始之前显式覆盖启动播放器,而无需重建类。

这是一个天真的复杂示例代码。

#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 个输入之一)。

[编辑] 感谢乔纳森的建议,我在下面发布了解决方案。

谢谢乔纳森。这是我根据您的回复提出的解决方案。

这部分只是为了演示对无效参数的拒绝,删除它以查看它正确编译。

    ttcs.set_tic_tac_toe_start_player(9);
    std::cout << "player: " 
              << ttcs.get_tic_tac_toe_start_player() 
              << std::endl;

以下是解决方案

#include <iostream>
class TTCSystem
{
public:
    enum Player {PlayerX, PlayerO};
    void set_tic_tac_toe_start_player(Player p);
    char get_tic_tac_toe_start_player();
private:
    Player start_player;    
};
void TTCSystem::set_tic_tac_toe_start_player(Player p)
{
    this->start_player = p;
}
char TTCSystem::get_tic_tac_toe_start_player()
{
    return ((start_player == PlayerX) ? 'X' : 'O');
}

int main(int argc, char **argv)
{
    TTCSystem ttcs;
    ttcs.set_tic_tac_toe_start_player(TTCSystem::PlayerX);
    std::cout << "player: " 
              << ttcs.get_tic_tac_toe_start_player() 
              << std::endl;
    ttcs.set_tic_tac_toe_start_player(TTCSystem::PlayerO);
    std::cout << "player: " 
              << ttcs.get_tic_tac_toe_start_player() 
              << std::endl;
    ttcs.set_tic_tac_toe_start_player(TTCSystem::PlayerX);
    std::cout << "player: " 
              << ttcs.get_tic_tac_toe_start_player() 
              << std::endl;
    ttcs.set_tic_tac_toe_start_player(9);
    std::cout << "player: " 
              << ttcs.get_tic_tac_toe_start_player() 
              << std::endl;
    return 0;
}

最新更新