2016-02-25 25 views
0

我想创建一个函数“void set_tic_tac_toe_start_player(char c)”。这不是函数的实际名称,但它解释了它的意图。如何干净地创建typesafe枚举参数

我希望在编译时完成这个工作的原因是我想创建一个类来封装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个输入之一)。

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

+0

为什么在编译时检查?你从不在运行时使用这个函数? – Shumush

+0

你有一点。我可以将其设置为常量,我只是想要一个干净的程序员的覆盖。让我重述一下这个问题。 – Dmitry

+0

我添加了一个小的朴素代码来演示我想要做的一般想法。这不是最干净的独立演示,但我认为它有道理。 @Shumush我在编译时检查,这样我就可以提供一个简单的程序员界面来操纵井字棋系统,而无需重建类。 – Dmitry

回答

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