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


引言

今天做项目想用一个枚举类型,本来想这样写的:

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

由于不能看到其底层的实现,本身只能说“应该”,就上面这个例子,根据其用法,本人推测期内部现实的原理是这样的

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

Enum中定义中一系列与枚举相关的方法,查API可知:

protected  Object

clone()
          抛出 CloneNotSupportedException。

 int

compareTo(E o)
          比较此枚举与指定对象的顺序。

 boolean

equals(Object other)
          当指定对象等于此枚举常量时,返回 true。

 Class<E>

getDeclaringClass()
          返回与此枚举常量的枚举类型相对应的 Class 对象。

 int

hashCode()
          返回枚举常量的哈希码。

 String

name()
          返回此枚举常量的名称,在其枚举声明中对其进行声明。

 int

ordinal()
          返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。

 String

toString()
          返回枚举常量的名称,它包含在声明中。

static

<T extends Enum<T>> 
T

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】的用法相同。

 

 

从Java到C++——枚举类型的使用,布布扣,bubuko.com

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

上一篇:Recoil 中多级数据联动及数据重置的合理做法


下一篇:内置hooks(2):为什么要避免重复定义回调函数?