文档章节

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

自由的角马
 自由的角马
发布于 2015/01/10 13:57
字数 1594
阅读 18
收藏 0


引言

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

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()
          抛出 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,可以在定义枚举类型时给一个或几个成员指定值;

3,枚举成员是const的,初始化枚举成员时提供的初始化值必须是常量表达式;

4,枚举成员本身就是常量表达式,因此,可在任可需要用到常量值的地方使用枚举成员;


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

 

 

本文转载自:http://blog.csdn.net/luoweifu/article/details/21742845

自由的角马
粉丝 1
博文 269
码字总数 0
作品 0
文山
私信 提问
android开发教程(3)— jni编程之采用SWIG从Java调用C/C++

Android 从Java调用C/C++ 当无法用 Java 语言编写整个应用程序时,JNI 允许您调用C/C++本机代码。在下列典型情况下,您可能决定使用本机代码: 希望用更低级、更快的编程语言C/C++去实现对时...

刘小米_思聪
2014/09/16
4.6K
0
Thrift学习笔记—IDL基本类型

原文地址:http://zhwen.org/xlog/?p=658 thrift 采用IDL(Interface Definition Language)来定义通用的服务接口,并通过生成不同的语言代理实现来达到跨语言、平台的功能。在thrift的IDL中...

helight
2014/01/22
14.5K
0
Android JNI(一)——NDK与JNI基础

本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Native相互调用 Android JNI学习(四)——JNI的常用方法...

隔壁老李头
2018/05/09
0
0
Thrift RPC 系列教程(1)——Thrift语言

Thrift不是严格意义上的编程语言,但是却胜过很多编程语言,充满了美感。 基础数据类型 Thrift 这门编程语言提供了如下几种基础的数据类型: bool: A boolean value (true or false) byte: ...

浮生若梦的编程
2018/11/05
0
0
C++不垃圾,只是Java很傲慢

《Thinking in C++》及《Thinking in Java》的作者Bruce Eckel向来是个“拥C++反Java”派,他曾经不止一次的提到,C++语言特性的添加有多么的深思熟虑,而Java又是如何的把一些奇怪的东西不停...

AlphaJay
2010/04/15
758
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
昨天
5
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
昨天
8
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
昨天
10
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
昨天
6
0
PHP+Ajax微信手机端九宫格抽奖实例

PHP+Ajax结合lottery.js制作的一款微信手机端九宫格抽奖实例,抽奖完成后有收货地址添加表单出现。支持可以设置中奖概率等。 奖品列表 <div class="lottery_list clearfix" id="lottery"> ......

ymkjs1990
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部