引言
今天做项目想用一个枚举类型,本来想这样写的:
enum Move {left, right, up, down}; Move move = Move.left; if(move == Move.left) { cout << "move up" << endl; }
结果不行,这是怎么回事,原来在C++里不允许这样使用,C++中枚举的用法和Java还不一样。然后我的纳闷了,非要把枚举类型的用法觉察透不可。
枚举是一组具有相似含意的常量的组合,我们在项目中常常会用到这种枚举类型。
Java中的枚举类型:
Java 中的枚举类型采用关键字enum 来定义,是一个特殊的类,从jdk1.5才有的新类型,所有的枚举类型都是继承自Enum 类型。Enum的定义如下:
public abstract class Enum<E extends Enum<E>>extends Object implements Comparable<E>, Serializable
【例1】枚举的简单使用
enum Move{left, right, up, down}; public static void main(String args[]) { System.out.println(Move.left); System.out.println(Move.right); System.out.println(Move.up); System.out.println(Move.down); }
结果如下:
left
right
up
Down
上面这段代码中,Move其实是一个类,应该是一个Enum的子类。left, right, up, down是Enum的对象,应该是Move类中public static成员,Move中还有三个 static方法:
public static Move[] values();
public static Move Move.valueOf(String name);
public static T Move.valueOf(Class<T> enumType, String name);
由于不能看到其底层的实现,本身只能说“应该”,就上面这个例子,根据其用法,本人推测期内部现实的原理是这样的
Enum中定义中一系列与枚举相关的方法,查API可知:
protected Object |
clone() |
||
int |
|||
boolean |
|||
getDeclaringClass() |
|||
int |
hashCode() |
||
name() |
|||
int |
ordinal() |
||
toString() |
|||
|
valueOf(Class<T> enumType, String name) |
【例2】enum中其它的用法
enum Move{left, right, up, down}; public static void main(String args[]) { Move m = Move.down; System.out.println(m); Move[] moves = Move.values(); System.out.println(moves[0]); Move m2 = Move.valueOf("right"); System.out.println(m2); System.out.println(Move.up.name()); System.out.println(Move.up.ordinal()); }
结果如下:
down
left
right
up
2
参考文章:
http://blog.csdn.net/wgw335363240/article/details/6359614
C++中的枚举类型:
定义的格式:
enum [EnumeName] {<item1>, <item2>...<itemi>}[name]; (1)
说明:
[]:表示可选,可以有,也可以缺省不写;
EnumeName:枚举的类型名;
name:枚举的对象名;
C++11标准后,枚举又分为两种类型:不限定作用域和限定作用域,不限定作用域的类型也就是上面的定义(1),限定作用域的定义格式如下:
enum class (struct)[EnumeName] {<item1>, <item2>...<itemi>}[name]; (2)
下面以例子的形式分别介绍这两种枚举类型的用法:
不限定作用域
【例3】:引言中问题的正确写法
//移动的枚举类型
enum Move {left, right, up, down}; Move move = Move::left; if(move == Move::left) { cout << "move up" << endl; }
【例4】枚举成员的访问
//移动的枚举类型 enum Move {left, right, up, down}; cout << left << endl; //可以直接访问枚举成员 cout << Move::left << endl; //通过枚举类型的作用域来访问 enum Direction{left, west}; //VS2010上编译不通过,提示:‘left‘ : redefinition; previous definition was ‘enumerator‘ //因为Move的left成员和Direction的left成员在相同的作用域下,重复定义
笔记:
1,枚举成员的作用域与枚举类型本身的作用域相同;
2,可以直接访问枚举成员,也可以通过枚举类型的作用域来访问对应类型的成员;
【例5】枚举对象的初始化和赋值
enum Move {left, right, up, down}; Move m1 = left; Move m2 = Move::right; Move m3 = m1; cout << m1 << endl; cout << m2 << endl; cout << m3 << endl;
结果:
0
1
0
笔记:
1,枚举对象可用枚举成员或另一个枚举对象对其进行赋值;
2,不限定作用域的枚举没有默认类型,不能用其它基本类型的变量对其进行赋值,如以下的形式赋值都是错误的:
Move m5 = 5;
int i =4;
Move m6 = i;
【例6】给枚举成员指定值
enum Move {left, right, up, down}; cout << left << " " << right << " " << up << " " << down << endl; enum Direction{east = 2, sourth, west = 3, north}; cout << Direction::east << " " << Direction::sourth << " " << Direction::west << " " << Direction::north << endl;
结果:
0 1 2 3
2 3 3 4
笔记:
1,枚举成员默认从0开始,依次加1;
2,可以在定义枚举类型时给一个或几个成员指定值;
【例7】基本数据类型赋值
enum Move : long{ left, right, up, down}; int i1 = left; int i2 = right; long l = up; double d = down; cout << i1 << endl; cout << i2 << endl; cout << l << endl; cout << d << endl;
结果为:
1
2
3
4
限定作用域
限定作用域的枚举类型,枚举成员作用域遵循常规的作用域准则,在枚举类型的作用域外不可访问;不同的枚举类型可以定义相同名字的枚举成员,因为其在各自的作用域内。
【例8】枚举成员的访问
enum class Move { left, right, up, down }; Move m1 = Move::left;//通过枚举类型的作用域来访问 //不可以直接访问枚举成员, 因为其在作用域外不可见 //Move m2 = right; //提示: ‘right‘ : undeclared identifier //Move中定义了left,在Direction中依然可以定义,互不冲突 enum class Direction{ left, west, east}; Direction d1 = Direction::left;
笔记:
1,iostream中的out没有实现对限定作用域的枚举类型,所有不能输出类似于枚举类型:cout << m1 << endl;
【例9】指定数据类型
enum class Move : long{ left =255, right, up, down}; Move m1 = Move::left;
笔记:
1,限定作用域的枚举类型可以指定数据类型
2,如果没有指定类型,则枚举成员的默认类型是int
限定作用域与不限定作用域的枚举类型对上面【例3】和【例6】的用法相同。