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++ 枚举类型的更多相关文章

  1. Qt::WindowFlags枚举类型解析

    在使用Qt设计的时候经常会看到QWidget控件的构造函数出现下面这样一句话: QWidget(QWidget *parent=0,Qt::WindowFlags f=0) QWidget *pare ...

  2. Asp.Net 将枚举类型(enum)绑定到ListControl(DropDownList)控件

    在开发过程中一些状态的表示使用到枚举类型,那么如何将枚举类型直接绑定到ListControl(DropDownList)是本次的主题,废话不多说了,直接代码: 首先看工具类代码: /// <su ...

  3. golang枚举类型 - iota用法拾遗

    在c#.java等高级语言中,经常会用到枚举类型来表示状态等.在golang中并没有枚举类型,如何实现枚举呢?首先从枚举的概念入手. 1.枚举类型定义 从百度百科查询解释如下:http://baike ...

  4. 第三条:用私有构造器或者枚举类型强化Singleton属性

    1.使用单元素的枚举类型 public enum Singleton implements Serializable { INSTANCE; private String field; public ...

  5. 在WPF中使用变通方法实现枚举类型的XAML绑定

    问题缘起 WPF的分层结构为编程带来了极大便利,XAML绑定是其最主要的特征.在使用绑定的过程中,大家都普遍的发现枚举成员的绑定是个问题.一般来说,枚举绑定多出现于与ComboBox配合的情况,此时我 ...

  6. 窥探Swift之别样的枚举类型

    想必写过程序的童鞋对枚举类型并不陌生吧,使用枚举类型的好处是多多的,在这儿就不做过多的赘述了.Fundation框架和UIKit中的枚举更是数不胜数,枚举可以使你的代码更易阅读并且可以提高可维护性.在 ...

  7. C#枚举类型的常用操作总结

    枚举类型是定义了一组"符号名称/值"配对.枚举类型是强类型的.每个枚举类型都是从system.Enum派生,又从system.ValueType派生,而system.ValueTy ...

  8. TypeScript中的枚举类型

    TypeScript拓展了Javascript原生的标准数据类型集,增加了枚举类型(enmu)和其他语言一 样 它提供我们一种数字类型的值,用来设置由于辨别的名字和方法 enum Students { ...

  9. Python 中的枚举类型~转

    Python 中的枚举类型 摘要: 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表示某些特定的有限集合,例如星期.月份.状态等. 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表 ...

随机推荐

  1. Windows用WinDbg分析蓝屏dump文件查找原因(转)

    WinDbg官方下载: http://msdl.microsoft.com/download/symbols/debuggers/dbg_x86_6.11.1.404.msi http://msdl. ...

  2. php图片上传检测是否为真实图片格式

    PHP 图片上传,如果不做任何判断的话,随便一个文件如 rar,zip,php,java等文件改个文件名,改个后缀就能以图片形式上传的服务器,往往会造成极大的危害! 工具/原料   PHP apach ...

  3. SD卡 TF卡 接口引脚定义

  4. CMoReader

    #ifndef __E3GLOGLOADBYFILE_H__ #define __E3GLOGLOADBYFILE_H__ #include "PubCommon\MemoryManager ...

  5. 关于新一代Android的一切Android L (2014-07-04)

    谷歌在今年的I/O大会上一改曾经的传统,由发布新版Android改为发布Android L的开发者预览版本,而其正式版本将会在今年秋天面世,这种方式将会方便开发者在正式版发布之前尽早对自己应用进行优化 ...

  6. Python学习(六)模块

    Python 模块 模块定义 随着程序越来越庞大,需要分隔成几个文件:也需要能在不同文件中复用函数.类和变量,而不是拷贝代码.为了满足这些需要,Python提供了模块. 简单来说,模块就是一个保存了P ...

  7. 关于TagHelper的那些事情——自定义TagHelper(格式化输出、依赖注入使用)

    自定义TagHelper的最后一步就是在Process方法或ProcessAsync方法中添加展现代码.熟悉WebControl开发的朋友都知道Render方法,在这个方法中会添加展现的Html元素和 ...

  8. HDU1230 火星A+B

    火星A+B Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  9. c++学习之多态(虚函数和纯虚函数)

    c++是面向对象语言,面向对象有个重要特点,就是继承和多态.继承之前学过了,就是一种重用类的设计方式.原有的类叫父类,或者基类,继承父类的类叫子类.在设计模式中,我们总是要避免继承,推荐用组合.因为继 ...

  10. MFC【6】文件I/O和串行化

    文件输入和输出(I/O)服务是所有操作系统的主要工作.Microsoft Windows提供了各种API函数用来读.写和操作磁盘文件.MFC将这些桉树和CFile类融合在面对对象的模型里.其中CFil ...