条款02:尽量以const,enum,inline替换#define
部分来源:https://blog.csdn.net/weixin_37992828/article/details/81117036
关于const
在使用宏定义的时候,比如
#define pi 3.14159
宏pi根本没有进入记号表,当使用这个宏但是编译错误时,只会提示是3.14159出现了错误。如果这一行宏定义出现在不是程序员自己写的头文件时,也就查不到这个3.14159到底是出现在哪里了。因此,提倡使用常量来替换宏定义
const double pi = 3.14159;
关于enum hack
从一个例子开始吧
class Game {
private:
static const int GameTurn = 10;
int scores[GameTurn];
};
对于支持类内初始化的C++编译器,这段代码可以编译通过。
但是较老的C++编译器,可能不支持类内初始化,这样我们的静态常量,必须要在类外初始化。如下:
class Game {
private:
static const int GameTurn;
int scores[GameTurn];
};
const int Game::GameTurn = 10;
如果没有int scores[GameTurn];
,这段代码就可以用不支持类内初始化的编译器通过了。
但因为 int scores[GameTurn];
用到了GameTurn
,而GameTurn
的值不能确定。所以会报如下错误。
enum_hack.cpp:5: error: array bound is not an integer constant
这种情况下,如果我们仍然不想用硬编码的数字指定数组的大小,就可以考虑这篇文章的主角: enum hack
了。
使用enum hack
的技巧,其思想就是把GameTurn
定义为一个枚举常量。上面的代码可以写为:
class Game {
private:
// static const int GameTurn;
enum {
GameTurn = 10};
int scores[GameTurn];
};
// const int Game::GameTurn = 10;
这样代码就可以编译通过了。
《Effective C++》中这样描述enum hack
的好处:
enum hack
的行为更像#define
而不是const
,如果你不希望别人得到你的常量成员的指针或引用,你可以用enum hack
替代之。(为什么不直接用#define
呢?首先,因为#define
是字符串替换,所以不利于程序调试。其次,#define
的可视范围难以控制,比如你怎么让#define
定义的常量只在一个类内可见呢?除非你用丑陋的#undef
。- 使用
enum hack
不会导致 “不必要的内存分配”。 enum hack
是模板元编程的一项基本技术,大量的代码在使用它。当你看到它时,你要认识它。
关于inline
使用#difine宏定义的另一个作用是宏函数,但是宏函数只是长得像函数,实际并不是函数,只是单纯的文本替换
#define compareAB(a,b) f((a)>(b)?(a):(b))
上面的宏定义根据a,b的值调用函数f,函数f是一个真正的函数
那么根据传入++a>b和++a<b这两种情况,a的递增次数是不一样的
这种情况就是使用宏函数降低函数调用开销的弊端,那么为了解决这个问题,还同时要降低函数调用的弊端,可以使用inline函数
inline void compareAB(int& a, int&b) {
f(a>b?a:b);
}
此时的compareAB是一个真正的函数,还不用为每一个实参都加括号
总结:
1、对于纯变量,最好用const和enums替换#define
2、对于宏函数,最好用inline函数替换