您的位置:首页 > 其它

条款2:尽量以const、enum、inline替换#define

2015-05-28 09:26 267 查看
1> 以const替换#define

比如用const double Ratio = 1.653替换#define RATIO 1.653

因为宏定义在预处理阶段就会被替换成其所指代的内容,然后才是对替换后的内容进行编译,因此编译器永远不能发现宏的存在。此时如果宏变量RATIO出现问题,那么编译器只会报出是1.653出现问题,是不是相当莫名其妙?究其原因就是所使用的宏变量压根没进入到符号表中,编译器看不到。

如何定义类内常量,就是对该类而言只有一份的那种变量?当然我们会想到static,如果加上const会更好,但此时#define就不行了,如果用#define定义了所谓的私有宏,那么在其定义后都可以访问,因此#define没有scope限制,如下所示:

#include<iostream>

class GamePlayer
{
private:
static const int Nums = 5;  // 常量的声明而非定义
int scores[Nums];
#define NUMS 5              // 定义所谓的私有宏
};

int main()
{
std::cout << NUMS << std::endl;     // 可以随时访问,不受类作用域限制
return 0;
}


如上,此时的类内常量定义就没有任何意义了。

接着讨论static const定义,定义应该放在哪?

一般而言,我们所定义的类都放在头文件中,那么类内常量的定义当然是放在源文件中了,在源文件中就像下面这样定义即可:

const int GamePlayer::Nums;   // 常量在使用前必须定义

当然你也可以在声明时不初始化,等到定义时再赋值也是一样的。

2> 以enum替换#define

我们也可以使用enum来实现类内的常量定义,如下所示:

class GamePlayer
{
private:
 enum{ Nums = 5 };              // 以enum定义常量
int scores[Nums];
};


其实enum的行为和#define更像一些,因为我们不能取一个#define的地址,同样也不能取一个enum的地址,但是我们可以取一个const常量的地址。

3> 以inline替换#define

假设我们有如下宏定义:

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

可以替换如下:

template<typename T>
inline void callMax(const T& a, const T& b)
{
f(a > b ? a : b);
}


如上替换之后就不用再担心宏参数的加括号问题,同时也使代码变得简洁明了。再者说,定义类内的private inline函数也毫无问题,而#define绝对不能胜任。

总结:

对于单个常量,以const或enum替换#define定义。

对于带参数的宏,以inline函数替换#define定义。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: