zoukankan      html  css  js  c++  java
  • 《Effective C++》Item2:尽量以const,enum,inline替换#define


    1. 宏定义

    #define ASPECT_RATIO 1.653

    该宏定义ASPECT_RATIO也许从来没有被编译器看到,也许在编译器开始处理源码之前就已经被预处理器替换了。所以记号名称ASPECT_RATIO有可能没进入符号表(symbol table)中。所以,当你从这个常量得到一个编译错误信息时,这个错误信息可能会提到1.653而不是ASPECT_RATIO,如果这个ASPECT_RATIO被定义在一个非你写的头文件中,那么调试追踪这个错误更是麻烦。在调试阶段,visual stiduo和linux平台的gdb在调试的过程中无法查找定义的宏的值,因为符号表中没有这个符号,因此不能所见即所得,还必须通过阅读代码才能看到。

    2. 使用const定义常量

    解决上面的问题的办法就是,以一个常量替换上面的宏

    const double aspectRatio = 1.653//大写名称通常用于宏,因此这里改变名称写法

    从上面可以看出该常量有类型,double。它作为一个常量,肯定能被编译器看到,当然也就能进入符号表中了,进入了符号表的常量表中。

    3. class专属常量

    为了将常量的scope限制于class内,就必须让它成为class的一个成员;而为了确保此常量最多只有一份实体,必须让他让成为一个static成员。

    class GamePlayer
    {
    private:
        static const int NumTurns = 5;//常量声明式
        int scores[NumTurns];//使用该常量
    };
    

      这里看到的是NumTurns的声明式而非定义式。通常C++要求对所使用的任何东西提供一个定义式,但如果它是个class专属常量又是static且为整数类型(integral type例如ints、chars、bools),则需要特殊处理。只要不取他们的地址,就可以声明并使用他们而无需提供定义式。如果要取某个class专属常量的地址,就必须提供这个专属常量的定义式:

    const int GamePlayer::NumTurns;//NumTurns的定义

    要把这个statement放进一个实现文件而非头文件,同时由于class常量在声明时获得了初值,定义时就不可以再设置初值了。
    下面在举个例子说明用法:

    class MyTest
    {
        //“MyTest::maxNumber1”: 只有静态常量整型数据成员才可以在类中初始化
        //int maxNumber1 = 5;
    
        //“MyTest::maxNumber1”: 只有静态常量整型数据成员才可以在类中初始化
        //const int maxNumber2 = 5;
    
        //“MyTest::maxNumber1”: 只有静态常量整型数据成员才可以在类中初始化
        //static int maxNumber3 = 5;
    
        static const int maxNumber4 = 5;
        static const char cconst = 'A';
    public:
        //“MyTest::maxNumber2”: 必须在构造函数基/成员初始值设定项列表中初始化
        //如果有const常量成员,一定要在构造函数的初始值设定项列表中初始化
        MyTest()
        {
            cout << "MyTest Constructor!" << endl;
            cout << "maxNumber4 = " << maxNumber4<< endl;
            cout << "cconst4 = " << cconst << endl;
        }
    
    };
    

    总结一下:

    对于类的const类型的成员,一定要在构造函数的初始化列表中初始化,不管这个const成员变量是static还是非static的。

    对于static的成员变量,要在.cpp文件中提供一个定义式。对静态成员变量的初始化就在这个定义式中进行,但是后面可以在构造函数等的地方做修改。

  • 相关阅读:
    14_java之变量|参数|返回值|修饰符
    NYOJ 202 红黑树 (二叉树)
    NYOJ 138 找球号(二) (哈希)
    NYOJ 136 等式 (哈希)
    NYOJ 133 子序列 (离散化)
    NYOJ 129 树的判定 (并查集)
    NYOJ 117 求逆序数 (树状数组)
    NYOJ 93 汉诺塔 (数学)
    HDU 2050 折线分割平面 (数学)
    天梯赛L2-008 最长对称子串 (字符串处理)
  • 原文地址:https://www.cnblogs.com/stemon/p/4324486.html
Copyright © 2011-2022 走看看