`

C/C++中枚举类型(enum)

 
阅读更多

如果一个变量你需要几种可能存在的值,那么就可以被定义成为枚举类型。之所以叫枚举就是说将变量或者叫对象可能存在的情况也可以说是可能的值一一例举出来。

举个例子来说明一吧,为了让大家更明白一点,比如一个铅笔合中有一支笔,但在没有打开之前你并不知道它是什么笔,可能是铅笔也可能是钢笔,这里有两种可能,那么你就可以定义一个枚举类型来表示它!

enum box{pencil,pen};//这里你就定义了一个枚举类型的变量叫box,这个枚举变量内含有两个元素也称枚举元素在这里是pencil和pen,分别表示铅笔和钢笔。


在这里要说一下,如果你想定义两个具有同样特性枚举类型的变量那么你可以用如下的两种方式进行定义!

enum box{pencil,pen};

enum box box2;//或者简写成box box2;


再有一种就是在声明的时候同时定义。

enum {pencil,pen}box,box2; //在声明的同时进行定义!


枚举变量中的枚举元素系统是按照常量来处理的,故叫枚举常量,他们是不能进行普通的算术赋值的,(pencil=1;)这样的写发是错误的,但是你可以在声明的时候进行赋值操作!

enum box{pencil=1,pen=2};


但是这里要特别注意的一点是,如果你不进行元素赋值操作那么元素将会被系统自动从0开始自动递增的进行赋值操作,说到自动赋值,如果你只定义了第一个那么系统将对下一个元素进行前一个元素的值加1操作,例如

enum box{pencil=3,pen};//这里pen就是4系统将自动进行pen=4的定义赋值操作!



C++ 中的枚举类型继承于 C 语言。就像其他从 C 语言继承过来的很多特性一样,C++ 枚举也有缺点,这其中最显著的莫过于作用域问题——在枚举类型中定义的常量,属于定义枚举的作用域,而不属于这个枚举类型。例如下面的示例:

enum FileAccess {
Read = 0x1,
Write = 0x2,
};

FileAccess access = ::Read; // 正确
FileAccess access = FileAccess::Read; // 错误

C++枚举的这个特点对于习惯面向对象和作用域概念的人来说是不可接受的。首先,FileAccess::Read 显然更加符合程序员的直觉,因为上面的枚举定义理应等价于如下的定义(实际上,.NET 中的枚举类型便是如此实现的):

class FileAccess {
static const int Read = 0x1;
static const int Write = 0x2;
};

其次,这导致我们无法在同一个作用域中定义两个同样名称的枚举值。也就是说,以下的代码是编译错误:

enum FileAccess {
Read = 0x1,
Write = 0x2,
};

enum FileShare {
Read = 0x1, // 重定义
Write = 0x2, // 重定义
};

如果这一点没有让你恼怒过的话,你可能还没写过多少 C++ 代码 :-)。实际上,在最新的 C++0x 标准草案中有关于枚举作用域问题的提案,但最终的解决方案会是怎样的就无法未卜先知了,毕竟对于象 C++ 这样使用广泛的语言来说,任何特性的增删和修改都必须十分小心谨慎。

当然,我们可以使用一些迂回的方法来解决这个问题(C++ 总是能给我们很多惊喜和意外)。例如,我们可以把枚举值放在一个结构里,并使用运算符重载来逼近枚举的特性:

struct FileAccess {
enum __Enum {
Read = 0x1,
Write = 0x2
};
__Enum _value; // 枚举值

FileAccess(int value = 0) : _value((__Enum)value) {}
FileAccess& operator=(int value) {
this->_value = (__Enum)value;
return *this;
}
operator int() const {
return this->_value;
}
};

我们现在可以按照希望的方式使用这个枚举类型:

FileAccess access = FileAccess::Read;

并且,因为我们提供了到 int 类型的转换运算符,因此在需要 int 的地方都可以使用它,例如 switch 语句:

switch (access) {
case FileAccess::Read:
break;
case FileAccess::Write:
break;
}

当然我们不愿意每次都手工编写这样的结构。通过使用宏,我们可以很容易做到这一点:

#define DECLARE_ENUM(E) /
struct E /
{ /
public: /
E(int value = 0) : _value((__Enum)value) { /
} /
E& operator=(int value) { /
this->_value = (__Enum)value; /
return *this; /
} /
operator int() const { /
return this->_value; /
} /
/
enum __Enum {

#define END_ENUM() /
}; /
/
private: /
__Enum _value; /
};

我们现在可以按如下的方式定义前面的枚举,并且不比直接写 enum 复杂多少。

DECLARE_ENUM(FileAccess)
Read = 0x1,
Write = 0x2,
END_ENUM()

DECLARE_ENUM(FileShare)
Read = 0x1,
Write = 0x2,
END_ENUM()

分享到:
评论

相关推荐

    C++枚举类型enum与enum class的使用

    在C++中,枚举类型分为不限定作用域(enum)和限定作用域(enum class)。 2. enum与enum class的区别? (为什么需要限定作用域?) 答:枚举作用域是指枚举类型成员名字的作用域,起自其声明之处,终止枚举定义...

    c++中bool enum 引用等學習資料

    STL vector 容器介绍 C++中布尔类型 深入探讨C++中的引用 C/C++中枚举类型(enum)

    C++枚举类型实例

    C++枚举类型的简单实例,设置了enum result{win,lose,tie,cancle} 实现了这四种情况的顺序输出。

    C语言程序设计-枚举类型.pptx

    C语言设置了枚举类型。 枚举类型定义的一般形式为: enum 枚举名 { 枚举值表 }; 在枚举值表中应罗列出所有可用值,这些值也称为枚举元素。 例如:enum weekday { sun,mon,tue,wed,thu,fri,sat }; 5-2 枚举类型变量的...

    详解C++11强类型枚举

    枚举类型是C/C++中用户自定义的构造类型,它是由用户定义的若干枚举常量的集合。枚举值对应整型数值,默认从0开始。比如定义一个描述性别的枚举类型。 enum Gender{Male,Female}; 其中枚举值Male被编译器默认赋值为...

    c/c++ 学习总结 初学者必备

    答: 枚举(enum)作用:定义一组常量,而且这些常量组成了一个集合。当我们将emun参数传递给函数时,如果传递了一个不属于这个集合的参数,编译器报错。 区别: 枚举是类型,而宏没有类型。 枚举将检查其语法,而宏是...

    贪吃蛇C C++程序源代码

    1. //这个是背景的单元格数据结构 2. const length = 40; 3. const width = 20; 4. struct square{ 5. bool blocked; //是否有障碍物 6. bool food; //是否有食物 ... //枚举类型enum dir; //围墙;

    enum类型重定义解决方法

    常见的enum类型重定义的解决方法,清晰明了。

    一个月挑战C++

    8. 新手入门:C/C++中枚举类型(enum)....................................................... 14 9. 新手入门:C/C++中数组和指针类型的关系........................................... 16 10. 新手入门:关于...

    magic_enum:现代C ++的枚举(从字符串到字符串,从迭代到迭代)的静态反射,可与任何枚举类型一起使用,而无需任何宏或样板代码

    magic_enum:现代C ++的枚举(从字符串到字符串,从迭代到迭代)的静态反射,可与任何枚举类型一起使用,而无需任何宏或样板代码

    家庭财政管理系统.cpp

    // 自定义枚举类型 fi_type ,用来表示收入与支出 typedef enum _fi_type { income=1,// 收入 payout =-1 // 支出 } fi_type; // 家庭财务信息结构体 typedef struct _fi_info { int year; int month; ...

    中国地质大学c++试题

    3.定义如下枚举类型:enum Number{one=1, two=2, four=4, eight=8}; ,则下列语句正确的是__________. A)Number num=1; B)Number num=Number(20); C)Number num=Number(eight|0xFF); D)枚举类型Number的取值...

    C语言自动生成enum值和名字映射代码

    而这里面,enum类型的数据就很多,如果只是打印出它的整数值,显然会让测试人员很恼火,鬼知道那数字说的是什么。就算你给他个文档对着看,也丝毫不能得到原谅。最后,都得乖乖的把这个enum对应的名字打印

    C++小知识:尽可能使用枚举类

    PVS-Studio 是一个用于 C/C++ 的静态代码分析工具。该团队检测了 200 多个 C/C++ 开源项目,包括了 Unreal Engine、Php、Haiku、Qt 和 Linux 内核等知名项目。 下面这个 Bug 是在 Source SDK 的源代码中发现...

    初步剖析C语言编程中的结构体.doc

    C语言结构体,可谓是C强大...C语言中,结构体的声明、定义是用到关键字struct,就像联合体用到关键字union、枚举类型用到enum关键字一样,事实上,联合体、枚举类型的用法几乎是参照结构体来的。结构体的声明格式如下:

    iOS开发之枚举用法小结

    Enum,也就是枚举,从C语言开始就有了,C++、Java、Objective-C、Swift这些语言,当然都有对应的枚举类型,功能可能有多有少,但是最核心的还是一个—规范的定义代码中的状态、选项等“常量”。 举个例子,我们想要在...

    C++ Primer中文版(第5版)李普曼 等著 pdf 1/3

    C++ Primer中文版(第5版)[203M]分3个压缩包 本书是久负盛名的C++经典教程,其内容是C++大师Stanley B. Lippman丰富的实践经验和C++标准委员会原负责人Josée Lajoie对C++标准深入理解的完美结合,已经帮助全球无数...

    更好的枚举:C ++编译时枚举在单个头文件中的字符串,迭代

    具有清晰语法的反射型编译时枚举库,位于单个头文件中,没有依赖项。 在C ++ 11中,所有内容都可以在编译时使用。 您可以转换您的枚举,对其进行循环, ,以,并将结果作为模板参数传递给constexpr函数。 所有的...

    C语言简明教程(编辑成页)

    C语言简明教程 一、基础篇 1.1Turbo C语言概述 1.2 C 语言的特点 1.3 Turbo C 概述 1.4 Turbo C 2.0的安装和启动 1.5 Turbo C 2.0集成开发...指针、结构、联合和枚举 结 构(struct) 联 合(union) 枚 举(enum)

    C++Primer(第5版 )中文版(美)李普曼等著.part2.rar

    C++ Primer中文版(第5版)[203M]分3个压缩包 本书是久负盛名的C++经典教程,其内容是C++大师Stanley B. Lippman丰富的实践经验和C++标准委员会原负责人Josée Lajoie对C++标准深入理解的完美结合,已经帮助全球无数...

Global site tag (gtag.js) - Google Analytics