C++中大家总是关注于类,结构体,模板,STL,很少会关注枚举或者联合体的用法,最近学习微软的MFC代码,发现简单的枚举和联合体也能玩出很多花样。
首先,枚举只是一些常量,假如我们需要在程序中设置一些常量,当然是指整形常量,比如某个控件的ID,颜色的RGB值等。当然遵从C++的面向对象,我们会把这些常量集中到一个类里,如果你想到使用加const的成员变量,那么你必须要保证这些成员变量在构造函数中被初始化,当然你在使用时也会很麻烦,你必须要创建一个对象才行。而如果使用static const修饰的成员变量,倒是可以避免上面的麻烦。这里要注意只有static const才可以在类中声明同时初始化,而如果只是static则需要在类外进行初始化。
class base
{
public:
static const int m = 100; //OK
static int n ;
};
int base::n = 100; //OK
不过无论如何,都没有使用枚举来得方便。
class base
{
public:
enum COLOR
{
RED,
BLACK,
GREEN,
BLUE
};
};
int main()
{
cout<<base::RED<<endl;
return 0;
}
接着,由于枚举值有自动递增的特点,利用这点会有很奇妙的用法。比如:
enum animal
{
TYPE_START = 0,
CAT = 0,
DOG,
FISH,
BIRD,
NUM_OF_TYPES
};
结果就是CAT=0,DOG=1,FISH=2,BIRD=3,NUM_OF_TYPES=4
,注意最后的NUM_OF_TYPES它要表示的是动物的种类,你发现它的值恰好为4,恰好等于动物的各类数,而TYPE_START不会因为和CAT都置0而出现语法错误。如此,在添加新类型、获取类型总数、遍历所有类型都很方便,代码也会优雅很多。
这样的递增特性还带来一个好处,将所有类型转换成位图,从而可以方便地实现类型过滤,例如:
const static uint64_t TYPE_MASK = \
1 << CAT |
1 << DOG |
1 << FISH |
1 << BIRD |
uint64_t(0);
枚举还有一个好的用处,那就是运用在成员函数的默认参数上,让magic num变得易于理解。比如我们有一个函数
void connect(int port=80, int status=404);
当然我们肯定不会愿意直接使用一个整数来作为默认参数,因为假如我们一个月后再来修改这个代码,我们很可能不记得80,404表示表示什么意思,以及为什么我们当时会使用80,404来作为默认参数。
对于以上问题,很多人的做法是使用宏,他们在一个头文件里定义上百个宏,以供使用,当需要修改默认参数时,只需要打开这个头文件,修改里面的宏就OK了,不过宏爆炸也是令人恐怖的。使用私有枚举却能很好的解决这个问题,我们相当于将默认参数集中起来,需要更改时只需要修改该类里的私有枚举就可以了。这在MFC里是普遍用到的,因为常常默认参数只是一些控件ID号,状态值,标志位,使用枚举要易懂得多,一看就知道这是一个OK按钮,那是一个CANCEL按钮。当然枚举有一个天生的缺陷,那就是它只是整型,类型比较弱,容易与普通整型产生混淆。