C++学习笔记之作用域为类的常量和作用域内的枚举

一、作用域为类的常量

有些情况下,使符号常量的作用域为类很有用。如,类声明(不是定义)可能使用字面值30来指定数组长度,由于该常量对于所有对象来说都是相同的,因此创建一个由所有对象共享的常量是个不错的主意,也许我们想像下面这样做:

1 class Weather
2 {
3 private:
4     const int Months = 12;   //声明一个常量
5     double temperature[Months];
6         ...
7 }

要注意的是,我们这是在声明阶段,需要在声明类的时候就有一个字符常量可以供我们使用,但是也正因为我们处于声明阶段,类的声明只是描述一下类的形式,并不给数据成员分配任何值(可以想象函数声明来理解,只是告诉编译器,函数名字,参数的类型,几个参数,这都是来描述形式而已,并不会给参数赋值,类也是类似),真正给数据成员分配值是在用这个类创建一个对象的时候(就如同真正给函数参数分配值的时候是在调用该函数的时候),因为只有创建对象后,才会分配在一个空间给你存储对象数据,否则就没有这个存储空间,所以上述声明,虽然表面上给Months赋了一个值12,但是还没有创建对象,就没有存储值得空间(好比你对派出所声明你家将要出生一个小孩,但是在小孩真正出生之前,派出所是不会给“小孩”分配户口一样),于是,Months其实没有值,那么用一个没有的值来声明数组的大小,当然是不对的。

有问题,就有办法,有两种方式可以实现这个目标,效果相同。

第一种方法是在类中声明一个枚举。在类中声明(不是定义哦)的枚举的作用域为整个类,如下:

1 class Weather
2 {
3 private:
4     enum {Months = 12};   //声明一个枚举
5     double temperature[Months];
6 ...
7 }

有的读者会疑惑,不是说了,声明的时候不给数据成员分配值吗,怎么会这样?这也正是要注意的,用这种方式声明枚举不会创建类数据成员,也就是说在用这个类创建对象时,所有对象中都不包含枚举,Months只是一个符号名称,即一个符号常量(而不是变量),在类的作用域之内,代码遇见它时,编译器将用12来替换它。也许还有读者疑惑,符号常量不需要存储空间吗?事实上,就是不需要,所谓符号常量,就是用一个字符串来替换程序中出现的标识符,和宏定义类似,内存中没有以符号常量命名的存储空间,上述程序,就是遇见Months就替换为12而已。

第二种方法是使用关键字static:

1 class Weather
2 {
3 private:
4     static const int Months = 12;
5     double temperature[Months];
6 ...
7 }

不是说好,声明时,对象没有创建,所以没地存放值吗?这就是static的特性,它声明的变量是不依赖于对象的,也就是说它不存储在对象的空间中,它与其他静态变量(static)存储在一起,也就是说这个变量属于这个类,而不是属于具体的对象,但是这个类创建的对象当然可以使用它,打个比方,staic声明的静态变量就好比你们村口的一口百年古井,你用或者不用它,它就在那里,它属于整个村的,而不是村里的某一个人,但是呢,村里的每一个人都可以在里面打水,它当然不需要派出所给它分配户口,哈哈……

 二、作用域内的枚举(C++11)

注:C++11是2011年创建的C++新标准,在C++98基础上做了改动而成。

传统的枚举存在一些问题,其中之一就是连个枚举中定义的枚举量可能发生冲突,如:

1 enum egg {Small, Medium, Large, Jumbo};
2 enum t_shirt {Small, Medium, Large, Xlarge};

将无法通过编译,因为egg Small和t_shirt Small位于相同的作用域内,它们将发生冲突。C++11提供了一种新枚举,作用域为类,如:

1 enum class egg {Small, Medium, Large, Jumbo};
2 enum class t_shirt {Small, Medium, Large, Xlarge};

也可使用关键字struct代替class. 无论哪种方式,都需要使用枚举名来限定枚举量:

1 egg choice = egg::Large;         //the Large enumerator of the egg enum
2 t_shirt Floyd = t_shirt::Large;  //the Large enumerator of the t_shirt enum

枚举量的作用域为类后,不同枚举定义中的枚举量就不会发生冲突了。

C++学习笔记之作用域为类的常量和作用域内的枚举

时间: 2024-10-14 10:41:37

C++学习笔记之作用域为类的常量和作用域内的枚举的相关文章

javascript学习笔记---ECMAScriptECMAScript 对象----定义类或对象

使用预定义对象只是面向对象语言的能力的一部分,它真正强大之处在于能够创建自己专用的类和对象. ECMAScript 拥有很多创建对象或类的方法. 原始的方式 因为对象的属性可以在对象创建后动态定义(后绑定),类似下面的代码: var oCar = new Object; oCar.color = "blue"; oCar.doors = 4; oCar.mpg = 25; oCar.showColor = function() { alert(this.color); };不过这里有一

java学习笔记07--日期操作类

java学习笔记07--日期操作类 一.Date类 在java.util包中定义了Date类,Date类本身使用非常简单,直接输出其实例化对象即可. [java] view plaincopy public class T { public static void main(String[] args) { Date date  = new Date(); System.out.println("当前日期:"+date); //当前日期:Thu May 16 23:00:57 CST 

Java学习笔记_23_List接口实现类

23.List接口实现类: List接口继承了Collection接口,它是一个允许存在重复项的有序集合. 1>实现类ArrayList: ArrayList类支持可随需要而增长的动态数组.数组列表以一个原大小被创建,当超过了它的大小, 类集自动增大,当对象被删除后,数组就可以缩小. 优点:ArrayList类对于使用索引取出元素用较高的效率,他可以用索引快速定位对象. 缺点:ArrayList类对于元素的删除或插入速度较慢. 构造方法: · ArrayList(): 构造一个初始容量为10的空

Unity3d之Hash&Slash学习笔记(一)--角色属性类的构架

角色属性类的构架 角色属性类有8个类,继承关系如下图: 每个类的具体作用见之后的随笔 Unity3d之Hash&Slash学习笔记(一)--角色属性类的构架

CSS学习笔记——盒模型,块级元素和行内元素的区别和区别

今天本来打算根据自己的计划进行前端自动化的学习的,无奈早上接到一个任务需求需要新增一个页面.自从因为工作需要转前端之后,自己的主要注意力几 乎都放在JavaScript上面了,对CSS和HTML这方面其实基础真的很差,今天在写页面的时候就被浮动啊.内外边距啊这些耽误了不少时间. 反思一下,自己确实在这些基础方面的不足很多,所以今后的学习笔记主要是我在工作中遇到的一些问题和他们的解决方法.其中可能中会有JS.CSS.HTML各方面的,我会把自己每一天学到的内容都记录一下,辅助自己打好基础. 今天在

[Java学习笔记]-Java对象和类

Java是完全面向对象的高级语言,其基本的操作基本都是针对相应的对象和类.面向对象的程序是由对象组成的,每个对象包含对用户公开的特定功能部分和隐藏的实现部分.对应面向对象的语言,还有一种面向过程的语言,如C语言.面向对象的语言是在面向过程语言的基础上发展而来的.面向对象(OOP,全称为Object-Oriented-Programer,下文简称为OOP)相对于面向过程的语言而言,其优势在于很多问题的解决方法被封装在对象里,有时只需要创建这样的对象就可以解决我们的问题,而不必关心其具体实现细节,这

C++ 学习笔记之---对象和类

参考自<C++ Primer Plus 6th Edition>和 <C++ Primer 5th Edition> (本博文中知识点较为零散和基础,主要用于本人的学习回顾) 访问所创建对象的公有成员 1. 自动存储类对象:  "句点方法" 2. 动态存储类对象(使用new):  我们创建了一个匿名的对象,并把这个对象的地址传给了一个指针.我们可以使用指针的指向符"->"来访问公有成员,也可以使用"*"对指针进行反引

ArcGIS API for JavaScript 4.2学习笔记[24] 【IdentifyTask类】的使用(结合IdentifyParameters类)(第七章完结)

好吧,我都要吐了. 接连三个例子都是类似的套路,使用某个查询参数类的实例,结合对应的Task类,对返回值进行取值.显示. 这个例子是Identify识别,使用了TileLayer这种图层,数据来自Server的MapServer. 结果演示 戳不同的地方会有不同的识别结果. 我对TileLayer不是很了解,这一例仅针对有了解的同学,做一个IdentifyTask的解释. IdentifyTask/IdentifyParameter/IdentifyResult三个类 既然是一样的套路,那么先对

Scala2.11.7学习笔记(七)类和对象

鲁春利的工作笔记,好记性不如烂笔头 apply 需要构造有参数需求的伴生对象时,可定义并使用apply方法. class HelloWorld (var m : String, var n : Char) {     println("I'm class HelloWorld!");     def speak () {         println("Class HelloWorld Speak.");     } } object HelloWorld {