C++ 枚举类型的思考

简介:

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


==============================================================================
本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/19/2405456.html,如需转载请自行联系原作者
相关文章
|
6月前
|
存储 编译器 Shell
【C++基础语法 枚举】解析 C/C++ 中枚举类型大小值
【C++基础语法 枚举】解析 C/C++ 中枚举类型大小值
68 0
|
5月前
|
存储 安全 API
C++一分钟之-C++中的枚举类型(enum class)
【6月更文挑战第25天】C++的`enum class`(强类型枚举)在C++11中引入,增强了枚举的作用域和类型安全,减少命名冲突。它要求使用全名(如`Color::Green`)访问枚举成员,并能显式指定底层类型。常见问题包括默认值非0、隐式转换和范围溢出,解决办法是明确赋值、显式转换和选择合适底层类型。高效技巧包括用于状态机、作为函数参数、创建别名和迭代。掌握这些能提升代码质量。
148 0
|
6月前
|
安全 C++
C++程序中的枚举类型
C++程序中的枚举类型
50 1
|
6月前
|
程序员 测试技术 C++
[C++] enum枚举类型用法
[C++] enum枚举类型用法
94 0
|
6月前
|
编译器 Linux C++
C++ “美中不足” --->强枚举类型
C++ “美中不足” --->强枚举类型
|
C++
【C++知识点】枚举类型
【C++知识点】枚举类型
139 0
|
C++
C++ 用枚举类型替代宏定义连续的常量
C++ 用枚举类型替代宏定义连续的常量
106 0
|
C语言 C++
C++ 结构体 共用体 枚举类型 自定义数据类型 宏定义解析
C++ 结构体 共用体 枚举类型 自定义数据类型 宏定义解析
150 0
|
C++ 知识图谱
2013级C++第1周(春)项目——枚举类型与结构体初步
课程主页在:http://blog.csdn.net/sxhelijian/article/details/11890759 【项目0-闲谈几点】  学习信息技术的大学生,在初接触行业,就能够进入到专业社区,有机会了解行业最新进展、享受海量资源、接触专业人士、获得实践机会,也给自己创造了一个全新、开放的展示空间,我们可以拥抱这样的机会。  与互联网相关的大学生,学习程序设计课程过程中,就同互
991 0