您的位置:首页 > 编程语言 > C语言/C++

《Effect C++》学习------条款02:尽量以const,enum,inline替换#define

2016-08-11 13:12 337 查看
尽量以const, enum, inline替换#define的意思是: 宁可以编译器替换预处理器。

为什么要用const代替宏? 原因太多, 我不一一列举。 看程序:

为啥用const代替宏呢?

#include <iostream>
using namespace std;

#define PI 3.14

int main()
{
cout << PI << endl;

return 0;
}


其中PI是一个宏, 不是一个变量, 所以预编译器提前处理了它, 编译器对它完全没有感知,无法调试。 所以, 宏容易引起错误, 且不便于调试。

- 为什么要以enum带代替宏呢? 看看下面这个糟糕的程序吧:

#include <iostream>
using namespace std;

#define RED 0
#define BLACK 1
#define GREEN 2
#define YELLOW 3

int main()
{
return 0;
}


看看, 逻辑没个逻辑, 而且啰嗦, 还不如写成:

#include <iostream>
using namespace std;

enum
{
RED,
BLACK,
GREEN,
YELLOW
};

int main()
{
return 0;
}


为何用inline代替宏呢?看下面例子:

#define square(a) a * a


在main函数中调用时,可能会这样square(3),计算的是3的平方,这是OK的,但如果换成是square(1+2),计算的还是3的平方吗?注意这时编译器解释成1 + 2 * 1 + 2,这样2 * 1的优先级高一些,所以先做了,这就出问题了。

好的,这是常见的错误,有些程序员可能认为多加括号就行,比如:

#define square(a) (a) * (a)


这的确可以避免上面所说的优先级的问题,但万一调用时是这样写的呢?

int main()
{
int v = 3;
squre(++v);
}


本意是想求4的平方,但编译器会翻译成
(++v)*(++v)
,这样v就被加了两次,这个结果肯定不是你想要的!

一句话,带参的宏很容易出问题,特别是针对复合操作(一句话做了不止一件事情)时,bug频出。

解决这个问题的方法是:用函数替换!因为函数调用时,若实参是表达式,总是会先计算这个表达式的值,再去进行调用的,不会出现宏展开时的bug。

还要注意类专属常量可以使用一下两种方法:

-
static(静态) const(常) T(类型) variable(变量名) = Num(变量值);
的方法

-
enum(枚举) { variable(变量名) = Num(变量值) };
的方法

请记住:

[x] 对单纯常量,最好以const对象或enums替换#defines。

[x] 对于形似函数的宏,最好改用inline函数替换#defines。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: