C++ 在类中声明枚举
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2503807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Declaring an enum within a class
提问by bporter
In the following code snippet, the Color
enum is declared within the Car
class in order to limit the scope of the enum and to try not to "pollute" the global namespace.
在以下代码片段中,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) Is this a good way to limit the scope of the Color
enum? Or, should I declare it outside of the Car
class, but possibly within its own namespace or struct? I just came across this article today, which advocates the latter and discusses some nice points about enums: http://gamesfromwithin.com/stupid-c-tricks-2-better-enums.
(1) 这是限制Color
枚举范围的好方法吗?或者,我应该在Car
类之外声明它,但可能在它自己的命名空间或结构中声明吗?我今天刚看到这篇文章,它提倡后者并讨论了一些关于枚举的好点:http: //gamesfromwithin.com/stupid-c-tricks-2-better-enums。
(2) In this example, when working withinthe class, is it best to code the enum as Car::Color
, or would just Color
suffice? (I assume the former is better, just in case there is another Color
enum declared in the global namespace. That way, at least, we are explicit about the enum to we are referring.)
(2)在本例中,工作时内的类,它是最好的代码的枚举如Car::Color
,还是只是Color
足够?(我认为前者更好,以防万一Color
在全局命名空间中声明了另一个枚举。这样,至少,我们明确了我们所指的枚举。)
采纳答案by Peter Alexander
If
Color
is something that is specific to justCar
s then that is the way you would limit its scope. If you are going to have anotherColor
enum that other classes use then you might as well make it global (or at least outsideCar
).It makes no difference. If there is a global one then the local one is still used anyway as it is closer to the current scope. Note that if you define those function outside of the class definition then you'll need to explicitly specify
Car::Color
in the function's interface.
如果
Color
是特定于Car
s 的东西,那么这就是您限制其范围的方式。如果您打算Color
使用其他类使用的另一个枚举,那么您最好将其设为全局(或至少在外部Car
)。没有什么不同的。如果有一个全局的,那么无论如何仍然使用本地的,因为它更接近当前范围。请注意,如果您在类定义之外定义这些函数,则需要
Car::Color
在函数的接口中明确指定。
回答by Andreas Florath
Nowadays - using C++11 - you can use enum classfor this:
如今 - 使用 C++11 - 您可以为此使用枚举类:
enum class Color { RED, BLUE, WHITE };
AFAII this does exactly what you want.
AFAII 这正是您想要的。
回答by Sergey Teplyakov
I prefer following approach (code below). It solves the "namespace pollution" problem, but also it is much more typesafe (you can't assign and even compare two different enumerations, or your enumeration with any other built-in types etc).
我更喜欢以下方法(下面的代码)。它解决了“命名空间污染”问题,而且类型安全得多(您不能分配甚至比较两个不同的枚举,或者您的枚举与任何其他内置类型等)。
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;
};
Usage:
用法:
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
I create macro to facilitate usage:
我创建宏以方便使用:
#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),
Usage:
用法:
DEFINE_SIMPLE_ENUM(Color,
((Red, 1))
((Green, 3))
)
Some references:
一些参考:
- Herb Sutter, Jum Hyslop, C/C++ Users Journal, 22(5), May 2004
- Herb Sutter, David E. Miller, Bjarne Stroustrup Strongly Typed Enums (revision 3), July 2007
- Herb Sutter,Jum Hyslop,C/C++ 用户杂志,22(5),2004 年 5 月
- Herb Sutter、David E. Miller、Bjarne Stroustrup 强类型枚举(修订版 3),2007 年 7 月
回答by Matthieu M.
In general, I always put my enums in a struct
. I have seen several guidelines including "prefixing".
一般来说,我总是把我的枚举放在一个struct
. 我看过一些指导方针,包括“前缀”。
enum Color
{
Clr_Red,
Clr_Yellow,
Clr_Blue,
};
Always thought this looked more like C
guidelines than C++
ones (for one because of the abbreviation and also because of the namespaces in C++
).
一直认为这看起来更像是C
指导方针而不是指导方针C++
(因为缩写,也因为 中的命名空间C++
)。
So to limit the scope we now have two alternatives:
因此,为了限制范围,我们现在有两种选择:
- namespaces
- structs/classes
- 命名空间
- 结构/类
I personally tend to use a struct
because it can be used as parameters for template programming while a namespace cannot be manipulated.
我个人倾向于使用 a ,struct
因为它可以用作模板编程的参数,而不能操作命名空间。
Examples of manipulation include:
操纵的例子包括:
template <class T>
size_t number() { /**/ }
which returns the number of elements of enum inside the struct T
:)
它返回结构内枚举的元素数T
:)
回答by Harvey
If you are creating a code library, then I would use namespace. However, you can still only have one Color enum inside that namespace. If you need an enum that might use a common name, but might have different constants for different classes, use your approach.
如果您正在创建代码库,那么我将使用命名空间。但是,该命名空间中仍然只能有一个 Color 枚举。如果您需要一个可能使用通用名称的枚举,但对于不同的类可能有不同的常量,请使用您的方法。