在一个类中声明一个枚举
在下面的代码片段中, 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-tricks-2-better-enums 。
(2)在这个例子中,当在类中工作时,最好将枚举编码为Car::Color
,还是只需要Color
就足够了? (我认为前者更好,以防万一在全局命名空间中声明另一个Color
枚举。那么,至less我们明确指出了我们所指的枚举。)
-
如果
Color
只是Car
的特定Car
那么这就是你限制范围的方法。 如果你将要有另一个Color
枚举,其他类使用,那么你可以使它成为全球(或至less外部Car
)。 -
没什么区别。 如果是全球性的,那么本地的一个仍然被使用,因为它更接近当前的范围。 请注意,如果您在类定义之外定义这些函数,则需要在函数的接口中显式指定
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)) )
一些有用的参考:
- Herb Sutter,Jum Hyslop,C / C ++ Users Journal,22(5),2004年5月
- 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枚举。 如果您需要一个可能使用通用名称的枚举,但对于不同的类可能有不同的常量,请使用您的方法。