在类中声明枚举

在下面的代码片段中,在 Car类中声明了 Color枚举,以便限制枚举的范围,并尽量不“污染”全局命名空间。

class Car
{
public:


enum Color
{
RED,
BLUE,
WHITE
};


void SetColor( Car::Color color )
{
_color = color;
}


Car::Color GetColor() const
{
return _color;
}


private:


Car::Color _color;


};

(1)这是限制 Color枚举范围的好方法吗?或者,我是否应该在 Car类之外声明它,但可能在它自己的名称空间或结构中声明它?我今天刚刚看到这篇文章,它提倡后者,并讨论了一些关于枚举的好点: http://gamesfromwithin.com/stupid-c-tricks-2-better-enums

(2)在这个例子中,当使用 内心类时,最好将枚举编码为 Car::Color,还是仅仅使用 Color就足够了?(我假设前者更好,以防在全局名称空间中声明了另一个 Color枚举。这样,至少我们对所引用的枚举是明确的。)

301121 次浏览

如果您正在创建代码库,那么我将使用命名空间。但是,在该命名空间中仍然只能有一个 Color 枚举。如果您需要一个枚举,它可能使用一个公共名称,但是对于不同的类可能有不同的常量,那么使用您的方法。

  1. 如果 Color是某些特定于 Car的东西,那么这就是限制其范围的方法。如果您要使用其他类使用的另一个 Color枚举,那么您不妨将其设置为全局的(或者至少在 Car之外)。

  2. 没什么区别。如果有一个全局的,那么无论如何都会使用本地的,因为它更接近于当前的范围。注意,如果在类定义之外定义这些函数,那么需要在函数的接口中显式指定 Car::Color

一般来说,我总是把我的枚举在一个 struct。我已经看到了几个指导方针,包括“前缀”。

enum Color
{
Clr_Red,
Clr_Yellow,
Clr_Blue,
};

总是认为这看起来更像是 C指南而不是 C++指南(因为它的缩写,也因为 C++中的名称空间)。

因此,为了限制范围,我们现在有两个选择:

  • 命名空间
  • 结构/类

我个人倾向于使用 struct,因为它可以用作模板编程的参数,而名称空间不能被操纵。

操纵的例子包括:

template <class T>
size_t number() { /**/ }

返回结构 T: 中枚举元素的个数

我更喜欢下面的方法(代码如下)。 它解决了“名称空间污染”的问题,但也更加安全(您不能分配甚至比较两个不同的枚举,或者您的枚举与任何其他内置类型等)。

struct Color
{
enum Type
{
Red, Green, Black
};
Type t_;
Color(Type t) : t_(t) {}
operator Type () const {return t_;}
private:
//prevent automatic conversion for any other built-in types such as bool, int, etc
template<typename T>
operator T () const;
};

用法:

Color c = Color::Red;
switch(c)
{
case Color::Red:
//некоторый код
break;
}
Color2 c2 = Color2::Green;
c2 = c; //error
c2 = 3; //error
if (c2 == Color::Red ) {} //error
If (c2) {} error

我创建宏来方便使用:

#define DEFINE_SIMPLE_ENUM(EnumName, seq) \
struct EnumName {\
enum type \
{ \
BOOST_PP_SEQ_FOR_EACH_I(DEFINE_SIMPLE_ENUM_VAL, EnumName, seq)\
}; \
type v; \
EnumName(type v) : v(v) {} \
operator type() const {return v;} \
private: \
template<typename T> \
operator T () const;};\


#define DEFINE_SIMPLE_ENUM_VAL(r, data, i, record) \
BOOST_PP_TUPLE_ELEM(2, 0, record) = BOOST_PP_TUPLE_ELEM(2, 1, record),

用法:

DEFINE_SIMPLE_ENUM(Color,
((Red, 1))
((Green, 3))
)

参考资料:

  1. Herb Sutter,Jum Hyslop,C/C + + 用户杂志,22(5) ,2004年5月
  2. 赫伯 · 萨特,大卫 · E · 米勒,比雅尼·斯特劳斯特鲁普《强类型 Enums 》(第三修订版) ,2007年7月

现在-使用 C + + 11-你可以使用 Ref = “ http://en.cpferences ence.com/w/cpp/language/enum”rel = “ noReferrer”> enum class :

enum class Color { RED, BLUE, WHITE };

这正是你想要的。