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()

最新文章

  1. pwm 占空比 频率可调的脉冲发生器
  2. 简历生成平台项目开发-STEP5初步界面demo实现
  3. C#对象先序列化然后反序列化时间丢失八小时的问题
  4. php使用内置的mcrypt_encrypt和mcrypt_decrypt进行字符串加密解密
  5. start a new android studio project not working
  6. 常用工具和API的网站收集
  7. partial(C# 参考)
  8. Mybatis中的collection、association来处理结果映射
  9. JS对象基础
  10. 关于ThinkPHP中Session不能夸模块/控制器使用的问题-网上的答案我做个补充
  11. 转:Node.js异步处理CPU密集型任务的新思路
  12. UIColor各种颜色转换
  13. Android studio 中国的垃圾问题解决
  14. Java I/O之NIO概念理解
  15. 探索 ConcurrentHashMap 高并发性的实现机制
  16. mongoDB学习手记2--建库、删库、插入、更新
  17. JS常见操作,日期操作,字符串操作,表单验证等
  18. 陌陌架构分享 – Apple Push Notification Service
  19. [Swift]LeetCode884. 两句话中的不常见单词 | Uncommon Words from Two Sentences
  20. python,os.path简单用法

热门文章

  1. CentOS 6.9/7通过yum安装指定版本的PostgreSQL
  2. Ubuntu下deb包的安装方法 - kevinhg的博客 - 博客频道 - CSDN.NET
  3. erlang 大神
  4. 如何使用花生壳 发布WCF服务 进行外网访问 z
  5. UVa 1329 - Corporative Network Union Find题解
  6. lodop同一页面一次性打印多次
  7. HTML:基本的标签
  8. 图片变换【Matrix】矩阵 简介
  9. Hadoop 基本架构
  10. 用curl抓取网站数据,仿造IP、防屏蔽终极强悍解决方式