zoukankan      html  css  js  c++  java
  • 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

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

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    【PAT甲级】1043 Is It a Binary Search Tree (25 分)(判断是否为BST的先序遍历并输出后序遍历)
    Educational Codeforces Round 73 (Rated for Div. 2)F(线段树,扫描线)
    【PAT甲级】1042 Shuffling Machine (20 分)
    【PAT甲级】1041 Be Unique (20 分)(多重集)
    【PAT甲级】1040 Longest Symmetric String (25 分)(cin.getline(s,1007))
    【PAT甲级】1039 Course List for Student (25 分)(vector嵌套于map,段错误原因未知)
    Codeforces Round #588 (Div. 2)E(DFS,思维,__gcd,树)
    2017-3-9 SQL server 数据库
    2017-3-8 学生信息展示习题
    2017-3-5 C#基础 函数--递归
  • 原文地址:https://www.cnblogs.com/90zeng/p/Cpp_scop_const_enum_static.html
Copyright © 2011-2022 走看看