### 枚举类型

在开发应用程序时，经常需要使用一组标记来描述对象的状态。例如一个记录集对象可以有打开状态、编辑状态和关闭状态。在程序中为了描述记录集的状态，通常定义一组常量值。例如：

const int RS_OPEN = 1; //打开状态

const int RS_EDIT = 2; //编辑状态

const int RS_CLOSE = 3; //关闭状态

如果需要编写一个函数根据参数描述的状态执行相关操作，可以编写一个类似下面的函数。

void OperateRecordset(int nState)

{

if (nState == RS_OPEN)

{

//执行打开操作

}

else if (nState == RS_EDIT)

{

//执行编辑操作

}

else if (nState == RS_CLOSE)

{

//执行关闭操作

}

}

这样，在程序中就实现了描述记录集的状态。在 OperateRecordset 函数中根据参数 nState 提供的不同状态，执行不同的操作。但是这样做存在一个严重的缺点，就是在 OperateRecordset 函数中无法限制用户传递的参数。因为 OperateRecordset 函数的参数是一个整数类型，用户可以随意提供一个整数作为函数的实际参数。这就违背了 OperateRecordset 函数的意图，从函数体中可以发现它只需要 3 个有意义的整数，即“1”、“2”、“3”。传递其他数值是没有意义的，但是传递其他的整数也会调用 OperateRecordset 函数，编译器并不能够限制用户提供的“没有意义的”参数。

枚举类型能够很好的解决上述问题，它能够将一组枚举常量与一个枚举类型名称关联。如果将函数的参数定义为某一个枚举类型，则只允许该枚举常量作为函数实际参数。在 C++中使用关键字 enum 定义一个枚举类型。例如：

enum RecordsetState {RS_OPEN, RS_EDIT, RS_CLOSE}; //定义枚举类型

在定义枚举类型时，可以为各个枚举常量提供一个整数值，如果没有提供整数值，默认第一个常量值为 0，第二个常量值为 1，以此类推。例如上面的代码中，RS_OPEN 的值为 0，RS_EDIT 的值为 1，RS_CLOSE 的值为 2。下面语句显示地为枚举常量提供数值。

enum RecordsetState {RS_OPEN = 3, RS_EDIT, RS_CLOSE = 6};

上面语句将枚举常量 RS_OPEN 设置为 3，将枚举常量 RS_CLOSE 设置为 6，没有为 RS_EDIT 显示地提供默认值，RS_EDIT 的数值为前一个枚举常量值加 1，因此 RS_EDIT 的数值为 4。

下面编写一个实例，使用枚举类型作为函数参数，这样在调用函数时，只能够为函数提供枚举常量，而不能通过将整数作为实际参数调用函数。

枚举类型作为函数参数

#include "stdafx.h"

#include <iostream.h>

enum RecordsetState {RS_OPEN = 3, RS_EDIT, RS_CLOSE = 6}; //定义枚举类型

void OperateRecordset(RecordsetState nState)

{

if (nState == RS_OPEN)

{

cout << "打开记录集" << endl;

}

else if (nState == RS_EDIT)

{

cout << "编辑记录集" << endl;

}

else if (nState == RS_CLOSE)

{

cout << "关闭记录集" << endl;

}

}

int main(int argc, char* argv[])

{

OperateRecordset(RS_OPEN); //调用函数 OperateRecordset

//OperateRecordset(3); //错误的函数调用

return 0;

}

在上面的实例中，函数 OperateRecordset 使用了 RecordsetState 枚举类型作为函数参数，这样就限制了实际参数只能是枚举常量 RS_OPEN、RS_EDIT 或 RS_CLOSE。虽然枚举常量对应于一个整数，但是不能够将整数作为 OperateRecordset 函数的实际参数。反过来，我们却可以将枚举常量作为整数对待，例如使用枚举常量参与数学运算是完全合法的。

int nRet = 10 * RS_OPEN; //枚举常量参数乘法运算

注意：可以用枚举变量赋值给整型变量，但是不允许将整型变量赋值给枚举变量。