C++慎用define,以及相关的替代的方法

有哪些问题:

在C++中,宏是一个非常好用的预处理功能,同时,它又有一些不好的地方,特别是用#define来实现macros,如果你这样做的话,你肯定要为每个参数都加上小括号,否则你懂得。但是这样仍然存在问题,说一个最近看到的例子:

1
2
/*求两个变量中最大的那个*/
#define THE_MAX(a, b) f((a) > (b) ? (a) : (b))

看着就头疼好吧- -!
当你这样用的时候:

1
THE_MAX(++a, ++b);

如果有人这样使用了这个宏,那么很明显的是,a和b总有一个会多累加一次。
那先总结一下#define的缺点吧,优点就不说了- -!

  1. #define不重视scope的概念,或者说没有,一旦被定义,就一直有效,除非在某个地方被#undef;
  2. 由于1的原因,#define不提供封装性,也就没有private这种权限之类的;
  3. 由于是预处理命令,所以定义的符号不会进入符号表内,对于调试的过程,很可能会让你头疼;

define的替代

1.对于#define I_VAR 123

const int iVar = 123可以替换上面的宏
有两个需要注意的地方:
(1) 当定义的是常量指针,需要const两次( const char* const iVar = "C++"),第一个const是防止值被改变,第二个const防止地址被改变。
(2) 当定义到class内时,需要用static来修饰这个变量,防止出现多个实体,代码如下:
1
2
3
4
5
6
7
class A {
private:
int i;
doubel d;
static const iVar = 15;
...
};

还有一个需要说一下,有些编译器需要你在.cpp文件内去定义这个常量:A::iVar;
由于声明时已经指定了值,所以定义时不要再去赋值,当然你也可以在声明时不指定任何值,而在定义时在确定这个值。

2. 对于#define FUNC(a, b) f((a) > (b) ? (a) : (b))

可以写一个inline函数来替代:

1
2
3
4
5
template<typename T>
inline void func(const T& a, const T& b)
{
f(a > b ? a : b);
}

最后,我们仍然离不开#define,但是我们要合理的去使用它,上面文章有不对的地方,欢迎指正,谢谢!

显示 Gitment 评论