#define
等预处理器命令并不被视为语言的一部分。#define
定义的常亮或许从来都没有进入到编译器,或许编译器没有使用#define的名称而只使用了其值。因此,当该define出现错误时,编译器给出的提示中如果写的是定义的值而不是名称,则难以被追踪(当这个宏不是你定义的时候,看到这个错误中的值甚至不知道这是宏定义还是变量的值还是返回值)。
- 使用’指向常量的常量指针’来替代宏定义的字符串
#define MBP MacBookPro
//替代:
const char* const mbp = "MacBookPro";
- 使用std::string来替代宏定义的字符串
const std::string rs7("Audi RS7"); //用于替代#define
- 如果老式编译器不允许在类内赋默认初值,而在类编译期间需要使用这个值,可以使用enum来定义常量
class Foo
{
public:
........
enum { x = 10};
}
==使用enum{something = x}
来替代#define
是很好的解决办法。==
- 务必对所有的宏中的每一个实参都加上小括号;务必禁止在使用宏函数的时候传入带有’++’、’–’运算符的参数
使用模板template inline函数来替代宏函数
#define CALL_WITH_MAX(a,b) \
f( (a) > (b) ? (a) : (b) )
替代:
template<typename T>
inline void callWithMax(const T& a,const T& b)
{
/*得到a、b的大值,以之调用f*/
f( a > b ? a : b); //f是一个函数
}
要点:
1. 使用inline
来模仿#define
宏函数,inline与宏函数一样不存在函数调用时的额外开销。
2. 使用const T&来接收参数,而不使用T和T&。(pass-by-reference-to-const)
总结
使用以上几种方法来替代宏定义,但是,宏定义并非可以完全不使用,#define尽量少用。
对于单纯的常量,使用const对象或enum替代。
对于宏函数(macros),尽量使用template inline函数来替代。