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

时间:2016-02-25 20:35:52

标签: c++ type-safety

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

我希望在编译时完成此操作的原因是因为我想创建一个类来封装TicTacToe系统,以便系统可以在游戏开始之前显式覆盖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;
}

该功能用于覆盖进入tic tac toe游戏的默认玩家,&#39; X&#39;或者&#39; O&#39;。

问题是任何字符都可以传递,而只想接受 {&#39; x&#39;,&#39; X&#39;,&#39; o&#39;,&#39; O&#39;}。

我可以创建一个枚举,但我担心enum不会强制执行类型检查。

我可以使用一个类来发明一个枚举类型,或者利用继承,但如果我走这条路,我不想重新发明轮子并做一个可怕的工作。

是否有更通用/优雅/简单的解决方案来创建类型安全的枚举?

我正在寻找一些能确保在编译时检查set_tic_tac_toe_start_player的输入,选择首先进入的玩家是有效玩家(4个输入中的一个)。

[编辑]感谢Jonathan提出的建议,我已经发布了以下解决方案。

1 个答案:

答案 0 :(得分:1)

谢谢乔纳森。以下是我根据您的回答提出的解决方案。

这部分仅用于演示拒绝无效参数,删除它以使其正确编译。

    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;
}