欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

条款02:尽量以const, enum, inline替换 #define

程序员文章站 2024-03-23 13:58:34
...

尽量以const, enum, inline替换 #define


const

在我们所编写的代码中经常会出现以下预处理命令

#define ASPECT_RATIO 1.653

注意:但是这并不是一个好的做法,因为很可能在编译器处理源代码之前,它就被(#undef)了这样就会造成符号名称ASPECT_RATIO没有进入符号表(symbol table)。

比如很可能在源代码文件的某一处会出现以下预处理命令

#undef ASPECT_RATIO



比较好的做法是以一个常量替换上述的宏,代码如下。

const double AspectRatio = 1.653
  • 此时的AspectRatio是属于源代码的一部分因此一定可以被编译器发现
  • 也更方便我们去追踪
  • 另一个优点是可以生成更小的码。比如,当我们使用#define方法时,编译器可能只是简单将ASPECT_RATIO替换成1.653这样可能就会造成更多的目标码(object code)

enum

对于class的专属常量。我们既会声明它为const同时也会声明它为static
比如很可能有如下代码。

class GamePlayer{
private:
    static const int NumTurns = 5; // 声明常量NumTurns(不是定义式)
    int  scores[NumTurns];         // 使用常量NumTurns
    ...
};

注意:然而这么做在某些情况下依然会发生问题,比如有些编译器会强制要求你在使用一个变量之前定义它。不然便会编译报错。



定义static变量代码如下

const int GamePlayer::NumTurns;     // 之所以没有赋初值是因为static在声明时就
                                    // 已经初始化了

注意:可这样做的话,依然会有问题有些编译器不支持在声明式中赋初始值,于是你可能会有如下做法。

class GostEstimate{
private:
    static const double FudgeFactor; // static class常量声明
                                     // 位于.h文件内
    ...
};
const double                         // static class常量定义
    CostEstimate::FudgeFactor = 1.35;// 位于.cpp文件内

注意:间接引入了一个新问题,前面的GamePlayer的数组坚持要在编译时间知道数组的大小。如果编译器报出“不允许static 整数型class常量完成 in class 初值设定”,则可使用enum hack的做法



enum hack代码做法如下

class GamePlayer{
private:
    enum{ NumTurns = 5};
    int scores[NumTurns];
};

inline

对于max, min我们经常会用一个宏去定义。比如

#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) > (b) ? (b) : (a))

注意:这里尽管用括号将宏参数括起来了,但是依然避免不了调用出错。比如会有如下代码

int a = 0, b = 0;
max(++a, b);        // a被累加2次
max(++a, b+10);     // a被累加1次



以下是用inline做法

template<typename T>
inline T max(const T& a, const T& b)
{
    return a > b ? a : b;
}
  • 这里这样做的好处
    • 不需要在函数本体中为参数加上括号
    • 不需要操心参数被运算多次
    • max是个函数遵守作用域(scope)和 访问规则