benxintuzi

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1> 以const替换#define

 比如用const double Ratio = 1.653替换#define RATIO 1.653

因为宏定义在预处理阶段就会被替换成其所指代的内容,然后才是对替换后的内容进行编译,因此编译器永远不能发现宏的存在。此时如果宏变量RATIO出现问题,那么编译器只会报出是1.653出现问题,是不是相当莫名其妙?究其原因就是所使用的宏变量压根没进入到符号表中,编译器看不到。

 如何定义类内常量,就是对该类而言只有一份的那种变量?当然我们会想到static,如果加上const会更好,但此时#define就不行了,如果用#define定义了所谓的私有宏,那么在其定义后都可以访问,因此#define没有scope限制,如下所示:

 1 #include<iostream>
 2 
 3 class GamePlayer
 4 {
 5 private:
 6     static const int Nums = 5;  // 常量的声明而非定义
 7     int scores[Nums];
 8     #define NUMS 5              // 定义所谓的私有宏
 9 };
10 
11 int main()
12 {
13     std::cout << NUMS << std::endl;     // 可以随时访问,不受类作用域限制
14     return 0;
15 }

如上,此时的类内常量定义就没有任何意义了。

接着讨论static const定义,定义应该放在哪?

一般而言,我们所定义的类都放在头文件中,那么类内常量的定义当然是放在源文件中了,在源文件中就像下面这样定义即可:

const int GamePlayer::Nums;   // 常量在使用前必须定义

当然你也可以在声明时不初始化,等到定义时再赋值也是一样的。

 

2> 以enum替换#define

我们也可以使用enum来实现类内的常量定义,如下所示:

1 class GamePlayer
2 {
3 private:
4     enum{ Nums = 5 };              // 以enum定义常量
5     int scores[Nums];
6 };

其实enum的行为和#define更像一些,因为我们不能取一个#define的地址,同样也不能取一个enum的地址,但是我们可以取一个const常量的地址。

 

3> 以inline替换#define

假设我们有如下宏定义:

#define CALL_MAX(a, b) f((a) > (b) ? (a) : (b))

可以替换如下:

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

如上替换之后就不用再担心宏参数的加括号问题,同时也使代码变得简洁明了。再者说,定义类内的private inline函数也毫无问题,而#define绝对不能胜任。

 

总结:

  • 对于单个常量,以const或enum替换#define定义。
  • 对于带参数的宏,以inline函数替换#define定义。

 

posted on 2015-05-28 09:26  benxintuzi  阅读(295)  评论(0编辑  收藏  举报