为啥需要枚举类型

编程语言中的所有特性都是为了满足某种需求,达到某个目的还出现.不会莫名其妙的出现在那.

枚举可以用来保存一组属性的值.enum的全称是enumeration意思是列举

看着这句话可能觉得太书面化了,不够通俗易懂.那举些通俗的例子说说.日常生活中我们特喜欢分类,比如读书时分啥数,理,化.当官的级别有啥省长,市长,县长.军队有军长,师长,团长.这样一组组的属性值就最适合用枚举类型来表示.当用一个软件时,有些页面会有很多单选按钮(radio button),这也特别适合用枚举来表示你举了哪一个.

光这样说你可能还不能体现枚举的好处.如果没枚举,表示一些组属性的值你只能用一组数字,或者一组字符串.

数字从字面上看不出任意意义,可读性非常差,所以很少用.那就假如要你通过比较字符串来做很多种类判断,比如 if(HisTitle == "stadholder")   else if(HistTile == "mayor") .如果让你敲个几十次你就知道是件多麻烦痛苦的事了,很多单词如果敲错一个意思就完全变了,这样出现bug了也不容易找到.老是复制粘贴也较麻烦.所以字符串是编辑麻烦,容易出错.如果要使用枚举就极大的方便我们敲代码,集成开发工具中的智能感应会给你提示,敲个点号就带出来了.而且枚举会做类型检查,不会像字符串那样只能靠你自己去对比.

枚举类型的内存分配问题

上面我们讲了如果没有枚举,一般会想到用数字或字符串表示某个类别.这样使用肯定不方便.也许你可能会想到用宏来表示.比如#define 市长 "mayor" 或者#define 市长 2

这自然是一个方法,但一来嘛在C++中是不太推荐用宏的,尽量少用.因为C++是强类型的语言,希望通过类型检查来降低程序中的很多错误,而宏只是在编译期前做简单替换,绕过了类型检查,失去了强类型系统的优势支撑. 二来嘛一组属性值都是相关联的信息,必须放到一起,放到一组.

关于常量的误解

枚举类型成员是常量

这句话怎么理解呢.也就是说enum  MyEnum{ one = 1 , two , three} ;

与 const int one = 1;  const int two = 2; const int three = 3; 差不多是一样的.

说到常量其实有个非常误导人的地方因为用宏#define 可以定义的我们说是常量,这里只涉及到简单的替换自然不可能存在内存分配问题.但是用const定义的也叫常量,而const定义常量貌似跟定义一般的变量只多个const关键字. 你可能会想当然认为常量都只是简单替换,所以不存在内存分配.那按这个逻辑,岂不是const定义的常量,枚举类型都没有内存分配?

实际上大部分时候确实是这样的.但并非总是如此,有些情况会需要分配内存的.

1.不需要分配内存的情况

如果定义常量const int one = 1;然后在其他地方只是把one作为右值赋值给其他变量那就不存在内存分配.但这里的常量跟#define定义的常量不同,宏定义的常量是编译前简单替换掉,而不需要做类型检查.而const定义的常量在编译时会帮类型检查,编译完之后再做替换.所以编译完之后就看不到const的信息了,转换成对应的值.const定义的信息只是保存在符号表中.

那同样,如果只是enum MyEnum{ one = 1 , two , three} ;这样定义一个枚举类型,然后也是简单的作右值赋值给其他变量.比如int num = MyEnum::one;那也只是保存信息在符号表中,编译后被替换掉了.

有人可能说如果用sizeof MyEnum测下会发现会是4(这是VS里面,不同的编译器可能不一样)于是认为不管是枚举里面有多少个元素内存分配都是4.实际上不是这意思,应该是定义一个MyEnum类型的枚举变量时会分配内存.这跟定义了一个类一样,你用sizeof去测一个为也会看到大小,但我们知道只有当类实例化之后才实际分配内存的.

2.需要分配内存的情况

1.)const int one;是类的成员变量 2. )extern const int one = 123;    3.)const int one = 1;    int* pConst = &one;

上面三种情况会需要分配内存.

而枚举类型,如果不是简单的去给其他变量赋值,而是去定义一个枚举类型变量.

比如MyEnum grade = MyEnum::one; //此时会分配4字节内存空间.(不过据说编译器会做优化,如果枚举类型所有值用两个字节表示就足够了,那实际分配的会就只会是两字节了.不一定就是默认的int类型的长度)

枚举类型具体用法

一般的用法是在全局域内定义一个枚举类型.比如

enum  MyEnum { one, two, three }

如果不显式指定,就会把第一个值默认赋值为0,然后递增1依次赋值.如果显式指定了某个值,则它下一个是它加1.

所以上面的例子中默认one = 0; two = 1; three= 2;

如果显式指定enum MyEnum { one, two = 3, three }

则one = 0; two = 3; three = 4;

定义一个枚举类型就是MyEnum grade = MyEnum::one;

类中使用枚举这是不太常用的用法.

在类中声明一个枚举后,定义枚举类型就可以省掉那个域作用前缀.比如MyEnum my = one; 在相同的作用域内也不能出现某个变量的名字和枚举中的元素名字相同,也就是不能出现其他变量名字是on,two, three

另外枚举还有一种少见的用法是

enum { one ,two ,three};  就是不指定一个名字,这样我们自然也没法去定义一些枚举类型了.此时就相当于const int one = 0;这样定义三个常量一样.

然后用的话就是int no = one;

C++枚举类型enum的更多相关文章

  1. 【转】java枚举类型enum的使用

    原文网址:http://blog.csdn.net/wgw335363240/article/details/6359614 java 枚举类型enum 的使用 最近跟同事讨论问题的时候,突然同事提到 ...

  2. C# 中的枚举类型 enum (属于值类型)

    原文 C# 中的枚举类型 enum (属于值类型) C# 支持两种特殊的值类型:枚举和结构. 声明枚举:声明时要声明所有可能的值. using System; using System.Collect ...

  3. 转载 java枚举类型enum的使用 (原文地址:http://blog.csdn.net/wgw335363240/article/details/6359614)

    java枚举类型enum的使用 最近跟同事讨论问题的时候,突然同事提到我们为什么java中定义的常量值不采用enmu枚举类型,而采用public final static 类型来定义呢?以前我们都是采 ...

  4. 枚举类型enum详解——C语言

    enum enum是C语言中的一个关键字,enum叫枚举数据类型,枚举数据类型描述的是一组整型值的集合(这句话其实不太妥当),枚举型是预处理指令#define的替代,枚举和宏其实非常类似,宏在预处理阶 ...

  5. 深入理解Java枚举类型(enum)

    https://blog.csdn.net/javazejian/article/details/71333103 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(en ...

  6. 人生苦短之Python枚举类型enum

    枚举类型enum是比较重要的一个数据类型,它是一种数据类型而不是数据结构,我们通常将一组常用的常数声明成枚举类型方便后续的使用.当一个变量有几种可能的取值的时候,我们将它定义为枚举类型.在Python ...

  7. 全面解读Java中的枚举类型enum的使用

    这篇文章主要介绍了Java中的枚举类型enum的使用,开始之前先讲解了枚举的用处,然后还举了枚举在操作数据库时的实例,需要的朋友可以参考下 关于枚举 大多数地方写的枚举都是给一个枚举然后例子就开始sw ...

  8. Java基础之枚举类型Enum的使用

    Java基础之枚举类型Enum的使用 定义 public enum AccruedCleanEnum { SPREAD("1","发票"),OTHER(&quo ...

  9. 《挑战30天C++入门极限》新手入门:C/C++中枚举类型(enum)

        新手入门:C/C++中枚举类型(enum) 如果一个变量你需要几种可能存在的值,那么就可以被定义成为枚举类型.之所以叫枚举就是说将变量或者叫对象可能存在的情况也可以说是可能的值一一例举出来. ...

  10. Asp.Net 将枚举类型(enum)绑定到ListControl(DropDownList)控件

    在开发过程中一些状态的表示使用到枚举类型,那么如何将枚举类型直接绑定到ListControl(DropDownList)是本次的主题,废话不多说了,直接代码: 首先看工具类代码: /// <su ...

随机推荐

  1. JMeter--PerfMon Metrics Collector监控内存及CPU

    1.需要准备的软件及插件 ServerAgent-2.2.1.zip JMeterPlugins-Standard-1.3.1.zip 2.jmeter上JMeterPlugins-Standard- ...

  2. javaScript面向对像

    1.创建对象 <script type="text/javascript"> function Flower(name,addre) { this.name=name; ...

  3. 09通过winfrom实现简单的播放音、视频

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  4. go实现生产者消费者

    package main import ( "fmt" "math/rand" ) func main() { ch := make(chan int) don ...

  5. jQuery属性和样式操作

    回顾 1. jquery基本使用 <script src="jquery.min.js"></script><script> $(functio ...

  6. uvm_reg_defines——寄存器模型(四)

    文件: src/marcos/uvm_reg_defines 类: 无 该文件是寄存器模型src/reg/* 文件对于的宏文件,主要定义了寄存器地址位宽,寄存器数据位宽,字节的大小.计算机从最初的8, ...

  7. jenkins+phantomjs环境搭建及使用

    #jenkins+phantomjs 前端性能自动化测试的安装和使用#gcc GNU编译器套件 https://gcc.gnu.org/ #nginx 高性能的HTTP和反向代理服务器 http:// ...

  8. show processlist使用介绍

    这个命令中最关键的就是state列,mysql列出的状态主要有以下几种: Checking table 正在检查数据表(这是自动的).Closing tables 正在将表中修改的数据刷新到磁盘中,同 ...

  9. 总结SQL Server窗口函数的简单使用

    总结SQL Server窗口函数的简单使用 前言:我一直十分喜欢使用SQL Server2005/2008的窗口函数,排名函数ROW_NUMBER()尤甚.今天晚上我在查看SQL Server开发的相 ...

  10. Git和SVN的5个基本区别

    如果你在读这篇文章,说明你跟大多数开发者一样对GIT感兴趣,如果你还没有机会来试一试GIT,我想现在你就要了解它了. GIT不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等.如果 ...