Effective_C++ (条款02) 尽量以 const,enum,inline替换 #define

条款可以改为——宁可以编译器替换预处理器,因为 #define 可能不被视为语言的一部分

  #define ASPECT_RATIO  1.653

解决之道是以一个常量替换宏(#define)

  const double AspectRatio = 1.653;

作为语言常量,AspecetRatio 肯定会被编译器看到,会进入记号表内。

用常量替换 #define 有两种特殊情况:

1. 定义常量的指针。

  常量定义式通常被放在头文件内(以便被不同的源码含入),因此有必要将指针声明为const。

   const char* const authorName = "Scott Meyers"; // 对于char* 字符串,要写两次 const

   const std :: string authorName( "Scott Meyers" ); // string 对象通常比其前辈 char* 合宜 

2. class 专属常量

  为了将常量的作用域限制在 class 内,必须让它成为 class 的一个成员,

  为确保此常量至多只有一份实体,必须让它成为一个 stactic 成员:

1     class GamePlayer
2     {
3 
4     private:
5       static const int NumTurns = 5;  // 常量声明
6       int scores[ NumTurns ];      // 使用常量
7       . . .
8     };

  如果要取某个 class 的专属常量的地址,还要提供定义式:

1     const int Gameplayer :: NumTurns;  // 该式放在 实现文件 而非头文件内

使用枚举类型:

1   class GamePlayer
2   {
3   private:
4     enum { NumTurns = 5 }; // the enum hack — 令 NumTurns 成为5的一个记号名称
5     int scores[ NumTurns ];
6     . . .
7   };

使用 enum hack 的理由:

1. enum hack 的行为某些方面说比较像 #define 而不像 const。

  取一个 const 的地址是合法的,但取一个 enum 的地址不合法。

  实现禁止获得一个 pointer 或 reference 指向某个整数常量

2. 实用主义

  许多代码用了它,是 模板元编程基础技术

另一个常见的 #define 误用情况是以它实现宏,宏看起来像函数,

但不会招致函数调用带来的额外开销:

1  #define CALL_WITH_MAX(a, b) f( (a) > (b) ? (a) : (b)  ) // 以a,b较大值调用f

这样长相的宏有着太多缺点。。。

我们可以获得宏带来的效率以及一般函数的所有可预料行为和安全性,

只要写出 template inline 函数:

1   template< typename T >
2   inline void callWithMax( const T& a, const T& b )  // 因为不知道T是什么,
3   {                               // 所以这里采用引用传递
4     f( a > b ? a : b );
5   }

你可以写一个 class 内的 private inline 函数,而宏无法完成此事

请记住:

  1. 对于单纯常量,最好以 const 对象或 enums 替换 #define

  2. 对于形似函数的宏,最好改用 inline 函数替换 #define

原文地址:https://www.cnblogs.com/kidycharon/p/10015477.html