C++ 枚举类型的思考

转载 2004年08月30日 00:24:00

http://blog.csdn.net/classfactory/archive/2004/08/29/87749.aspx

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

枚举类型Enum的含义分析

枚举类型是一种基本数据类型而不是构造数据类型,从jdk1.5才有的新类型,一般用来做全局常量。 特性: 1.它不能有public的构造函数,这样做可以保证客户代码没有办法新建一个enum的实例,可用...
  • pengkv
  • pengkv
  • 2015年03月11日 15:16
  • 1687

C语言enum枚举类型解析

在实际应用中,有的变量只有几种可能取值。如人的性别只有两种可能取值,星期只有七种可能取值。在 C 语言中对这样取值比较特殊的变量可以定义为枚举类型。所谓枚举是指将变量的值一一列举出来,变量只限于列举出...
  • skyflying2012
  • skyflying2012
  • 2014年04月01日 15:37
  • 117941

有缺陷的枚举类型 和 C++11中的强类型枚举

首先第一点,我们要弄清一个概念,那就是枚举类型的名字都在其父作用域空间 可见的。举个例子就一目了然了。 enum Type { General, Light, Medium, Heavy }; en...
  • friendbkf
  • friendbkf
  • 2015年08月17日 17:12
  • 1740

C++ 枚举类型作用域的思考

C++ 中的枚举类型继承于 C 语言。就像其他从 C 语言继承过来的很多特性一样,C++ 枚举也有缺点,这其中最显著的莫过于作用域问题——在枚举类型中定义的常量,属于定义枚举的作用域,而不属于这个枚举...
  • wangji163163
  • wangji163163
  • 2013年04月03日 10:10
  • 2898

C++ 枚举类型作用域的思考

C++ 中的枚举类型继承于 C 语言。就像其他从 C 语言继承过来的很多特性一样,C++ 枚举也有缺点,这其中最显著的莫过于作用域问题——在枚举类型中定义的常量,属于定义枚举的作用域,而不属于这个枚举...
  • ilufam1314
  • ilufam1314
  • 2017年06月15日 22:41
  • 99

C++ 枚举类型的思考

C++ 中的枚举类型继承于 C 语言。就像其他从 C 语言继承过来的很多特性一样,C++ 枚举也有缺点,这其中最显著的莫过于作用域问题——在枚举类型中定义的常量,属于定义枚举的作用域,而不属于这个枚举...
  • fmantianpiaolan
  • fmantianpiaolan
  • 2011年07月28日 17:11
  • 282

C++枚举类型实例

  • 2014年03月15日 21:27
  • 405B
  • 下载

新手入门:C/C++中枚举类型(enum)

出处:PConline2005年02月26日作者:管宁责任编辑:xietaoming     如果一个变量你需要几种可能存在的值,那么就可以被定义成为枚举类型。之所以叫枚举就是说将变量或者叫对...
  • lby978232
  • lby978232
  • 2012年02月29日 21:47
  • 282

从Java到C++——枚举类型的使用

引言 今天做项目想用一个枚举类型,本来想这样写的: enum Move {left, right, up, down}; Move move = Move.left; if(move == Move...
  • luoweifu
  • luoweifu
  • 2014年03月21日 20:51
  • 5021

深入理解C++枚举类型enum

为啥需要枚举类型 编程语言中的所有特性都是为了满足某种需求,达到某个目的还出现.不会莫名其妙的出现在那. 枚举可以用来保存一组属性的值.enum的全称是enumeration意思是列举 看着这句...
  • weiwenhp
  • weiwenhp
  • 2013年01月07日 16:02
  • 45119
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ 枚举类型的思考
举报原因:
原因补充:

(最多只允许输入30个字)