在一个类中声明一个枚举

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

 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-tr​​icks-2-better-enums 。

(2)在这个例子中,当类中工作时,最好将枚举编码为Car::Color ,还是只需要Color就足够了? (我认为前者更好,以防万一在全局命名空间中声明另一个Color枚举。那么,至less我们明确指出了我们所指的枚举。)

  1. 如果Color只是Car的特定Car那么这就是你限制范围的方法。 如果你将要有另一个Color枚举,其他类使用,那么你可以使它成为全球(或至less外部Car )。

  2. 没什么区别。 如果是全球性的,那么本地的一个仍然被使用,因为它更接近当前的范围。 请注意,如果您在类定义之外定义这些函数,则需要在函数的接口中显式指定Car::Color

现在 – 使用C ++ 11 – 你可以使用枚举类来做到这一点:

 enum class Color { RED, BLUE, WHITE }; 

AFAII这正是你想要的。

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

 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 

我创buildmacros以方便使用:

 #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 ++ Users Journal,22(5),2004年5月
  2. Herb Sutter,David E. Miller,Bjarne Stroustrup强types枚举(修订版3),2007年7月

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

 enum Color { Clr_Red, Clr_Yellow, Clr_Blue, }; 

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

所以为了限制范围,我们现在有两个select:

  • 命名空间
  • 结构/class

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

操作的例子包括:

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

它返回结构T中枚举的元素数量:)

如果你正在创build一个代码库,那么我会使用命名空间。 但是,在这个命名空间中你仍然只能有一个Color枚举。 如果您需要一个可能使用通用名称的枚举,但对于不同的类可能有不同的常量,请使用您的方法。