• 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

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

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    认证功能装饰器
    装饰器升级版
    装饰器
    闭包函数
    名称空间与作用域
    嵌套函数
    函数对象
    命名关键字参数
    函数单数的使用
    函数的定义与调用
  • 原文地址:https://www.cnblogs.com/90zeng/p/Cpp_scop_const_enum_static.html
Copyright © 2020-2023  润新知