zoukankan      html  css  js  c++  java
  • Book. Effective C++ item2-尽量使用const, enum, inline替换#define

    ##常规变量

    c++里面的#define后面的定义部分,是不算代码的一部分的。所以如果你使用#define:

    #define ASPECT_RATIO 1.653

    你希望这个代号ASPECT RATIO这个代号是能够被编译器加入到记号表(symbol table)里面,如果调试的时候,这个部分出现问题,能够很快的发现出来。但是很多时候我们的预处理器会把这个变量移除,只保留了一个1.653的常量,如果Debug的时候这个常量出现了错误,你是很难定位到自己需要修改代码的地方的,这就会造成我们在使用中Debug的时候很不方便。我们可以使用另外的方式来定义

    1
    const double AspectRatio = 1.653;

    修改之后,AspectRatio这个常量肯定会写入到记号表里面,是可以被编译器找到的。另外使用#define 可能会造成我们的代码里面有很多的object code 为 1.653, 但是使用const的方式,我们的代码里面就只会有一个AspectRatio

    如果是常量指针(constant pointers), 由于我们的常量一般是定义在头文件中的,所以我们需要将指针声明为const。如:

    const char* const authorName = "Scott Meyers";

    这里可以修改为String类型,使用String来存储字符串会比char*更加的合适,可定义为const std::string authorName("Scott Meyers");

    Class内部专属变量

    问题:限制常量的作用域是在Class内部,这样就要将这个常量作为Class的一个membeer, 这样就能够确保这个常量至多只有一个实体,并且必须将其声明为static member

    1
    2
    3
    4
    5
    class  {
    private:
    static const int NumTurns = 5;
    int scores[NumTurns];
    }

    因为这里面static const int NumTurns = 5;这是放在类的声明里面的,在这里就是一个变量的声明,并不是变量的定义,在内存里面是没有的。但是c++如果你在其他地方去使用的话,那是需要我们对这个进行先定义在使用的。如果要在其他地方使用,就需要提供一个定义:

    const int GamePlayer::Numturns;

    这个就可以放在你需要使用GamePlayer::NumTurns这个变量的文件里面,放在*.cpp文件里,而不是*.h文件中。

    注明:由于在类的声明中已经给GamePlayer::NumTurns进行了赋值操作,所以在这里单独直接定义就可以调用声明进行赋值操作。

    另外一种针对老式编译器不支持上述语法的解决方法:

    1
    2
    大专栏  Book. Effective C++ item2-尽量使用const, enum, inline替换#define3
    4
    5
    6
    7
    8
    //在头文件中
    class CostEstimate {
    private:
    static const double FudgeFactor; //static class 常量声明
    ...
    }
    //在实现文件中去做
    const double CostEstimate::FudgeFactor = 1.35;

    上面这种方式可能问题:class在编译区间需要一个class的长两只,就是编译器不允许static const int a 完成初始设定,这样我们就要使用到 the enum hack的方式进行补偿。理论:一个属于enumerated type的数值是可以当成ints来使用的

    1
    2
    3
    4
    5
    class  {
    private:
    enum {NumTurns = 5};
    int scores[Numturns];
    }

    说明: emum hack定义的内容,是不能够取地址的,取地址的操作是不合法的,而取#define的地址也是不合法的,但是取一个const的地址是合法的。如果不想让其他人获得这个pointer或者reference指向你的整数变量,enum就可以很好的实现这个功能。

    emum#define是绝对不会导致非必要的内存分配的。

    实现宏定义

    宏定义看起来像一个函数,但是不会导致函数的调用导致的额外开销,比如:

    #define CALL_WITH_MAX(a,b) f((a) > (b) ?(a):(b))

    首先,写这样的宏必须为所有的实参都加上小括号,否则其他地方调用的时候会出现问题。但即使加上了,如果你实现这样的代码:

    1
    2
    3
    int a = 5, b = 0;
    CALL_WITH_MAX(++a,b);
    CALL_WITH_MAX(++a,b+10);

    在调用之前,a会递增之后在去调用,并且是否递增取决与它和谁比较。

    小结

    • 对于单纯变量,使用const对象或者enums替换#define
    • 形如函数的宏,修改为inline函数替换#define
  • 相关阅读:
    Nodejs下载和第一个Nodejs示例
    永久关闭Win10工具栏的TaskbarSearch控件
    对称加密,非对称加密,散列算法,签名算法
    【转】TTL和RS232之间的详细对比
    zlg核心板linux系统中查看系统内存等使用信息
    Power BI后台自动刷新数据报错 The operation was throttled by Power BI Premium because there were too many datasets being processed concurrently.
    剪切板和上传文件内容获取
    CSS, LESS, SCSS, SASS总结
    文字程序
    electron 打包“ERR_ELECTRON_BUILDER_CANNOT_EXECUTE”
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12227176.html
Copyright © 2011-2022 走看看