如何检查类中已定义的枚举类型变量是否已分配给?

时间:2018-05-30 11:33:10

标签: c++ enums

我想检查一个类中的变量是否已设置?我该怎么办?

enum Color {
   red,
   blue
};
class example {
   Color c;
   void set_color(Color c) { this->c = c; }
   Color get_color() { return c; }
   bool check_color_is_set() {
       if (c == Color) {} // compile error
       if (c == NULL) {} // compile error
       return true;
   }

我想知道变量Color c是否已分配?

3 个答案:

答案 0 :(得分:7)

除了没有分配值(如在@code707's answer中),你可以做一些事情。

同样的方法,用户可以使用未初始化的类 - 缓解

如果用户正确设置了设置,则所有都基于存储bool。

使用get / set封装检查是否已设置:

class example {
private:
    Color color;
    bool isColourSet = false;

public:
    Color get_color() const;

    void set_color(Color newCol) {
       color = newCol;
       isColourSet = true;
    }
...

然后你可以根据自己的需要以各种方式使用这个bool:

抛出异常

    Color get_color() const {
       if (!isColourSet) throw some_exception; // It wasnt Set!! Throw
       return color;
    }

这样,您没有额外的枚举元素,并且可以防止通过抛出异常来抛出未定义的值。

返回错误代码

如果您不想抛出异常,可以传递一个return参数并返回错误:

ErrInt get_colour(Colour &out) const {
    if (!isColourSet) return STANDARD_ERROR_VAL;
    out = color;
    return STANDARD_SUCCESS_VALUE;
}

这与枚举中 Bad Value 的概念非常相似。

使用std::optional

c++17以来,您还有一种新方式std::optional,您可以选择返回(而不是抛出异常或返回错误值)。

class example {
public:
    std::optional<Color> get_colour() {
        return color;
    }
    void set_color(Color newColor) {
        color = newColor;
    }
private:
    std::optional<Color> color;
}

然后用户可以这样使用它:

auto myColor = myExample.get_colour();
if (myColour) { // Here you can check the optional
    myColour.get() // Do something with colour.
...

新方法,用户无法将类设置为错误状态 - 重新设计

与设置值并且必须检查它是否已正确设置相反,也许您可​​以设计类,使其永远不会处于无效状态。让我们来看看我们如何做到这一点:

1类型安全

我们不希望用户能够为我们不知道的颜色设置随机值。在当前的实现中,enum将是一个可以设置为任何int值的类型!有人做set_color(538)时意味着什么?我们可以用c ++ 11 enum class

解决这个问题
enum class Color {
    RED,
    BLUE
}

// This now causes a compiler error:
set_color(523);
// You can only use it like this:
set_color(Color::Red);

2构造函数参数

我们可以通过仅提供需要颜色的构造函数来强制用户选择初始颜色:

class example {
public:
    example(Color startColor) : color(startColor) {}        
...
private:
    Color c;
}

这意味着如果没有初始颜色,用户将无法创建该类。现在我们可以添加我们的set函数,以防用户想要更改颜色:

void change_color(Color newColor) {
    color = newColor;
}

3结论

现在你有一个类,用户永远无法让自己陷入无效的境地。我相信这比尝试检测用户是否填写了创建课程要好得多。

答案 1 :(得分:4)

“未分配”具有特殊价值怎么样?

enum Color {
   nocolor,
   red,
   blue
};
class example {
   Color c = nocolor;
   void set_color(Color c) { this->c = c; }
   Color get_color() { return c; }
   bool check_color_is_set() {
       if (c == nocolor) {} 

       return true;
   }

答案 2 :(得分:2)

如果您对使用boost library毫不犹豫,那么也许您可以使用boost::optional来完成。

#include <boost/optional.hpp>

enum Color {
   red,
   blue
};

class example 
{
   boost::optional<Color> c;
   void set_color(Color c) { this->c = c; }
   Color get_color() { return c; }
   bool check_color_is_set()
   {
     if( c ){
       // color is set
       return true;
     }
     else
     {
       // color is not set.
       return false;
     }
   }
}

默认情况下,boost::optional<Color> c的默认值为boost::none。您可以对其执行常规if检查,并查看是否已设置了某些内容。

以下是documentation of Boost Optional供您参考。

注意:我还没有使用STL版本的可选项,但如果您对使用Boost不感兴趣,也可以随时使用std::optional