使用cosnt替代#define的好处是,
1. 当程序出现编译错误时,程序会给出出错的变量名。如果采用预处理宏,宏名在预处理时被预处理器替换掉,宏名无法进入到程序的字符表中,因此在程序报错时只会给出错误处的数值。
2. 当程序采用const变量时,程序中只会存储此变量的一份存储,当采用宏定义时,程序中会出现多处存储。
取地址的合法性:取const变量的地址址合法,取enum变量的地址不合法,取#define 的地址不合法
Enum 不会有额外的内存分配,其特性和#define 相似,但其优点是可以指定为类的成员,#define则不可以指定为类的成员,而且#define的可视范围难以确定,无法将其使用范围局限在类内。
在初始化数组时需要指定数组的大小,除了使用#define 还可以使用enum-hack技术,此技术的特点是可以通过enum赋值数组大小,且变量范围可控,不会分配额外的内存,不会被其他指针获取到内存地址。
采用模板inline 函数代替宏定义的函数,可以起到程序输出不确定的问题。
例如:
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))
int a = 5, b = 0;
CALL_WITH_MAX(++a, b); //a被累加二次
CALL_WITH_MAX(++a, b+10); //a被累加一次
template<typename T>
inline void callWithMax(const T& a, const T& b)
{
f(a > b ? a : b);
}
同样可以将其指定为类内部函数。
对enum-hack技术的解释:
以下是支持类内初始化的代码:(可以通过编译)class Game {
private:
static const int GameTurn = 10;
int scores[GameTurn];
};
以下是不支持类内初始化的代码:(旧版本的编译器不支持类内初始化)
class Game {
private:
static const int GameTurn;
int scores[GameTurn];
};
const int Game::GameTurn = 10;
由于GameTurn的值对于数组来说不确定,因此会报错:
enum_hack.cpp : 4 : error: array bound is not an integer constant
这个时候enum_hack技术就起作用了:
class Game {
private:
// static const int GameTurn;
enum {GameTurn = 10};
int scores[GameTurn];
};
enum_hack技术是元编程技术中的一种,元编程可以在编译时计算出值作为常量,供运行时使用,因此其效果类似于#define 宏定义。