1. 对于单纯常量,最好以 const 对象或 enums 替换#defines。
2. 对于形似函数的宏(macros),最好改用 inline 函数替换 #defines。
-
使用 #define 的缺点
#define ASPECT_RATIO 1.653
记号名称 ASPECT_RATIO 也许从未被编译器看见;也许在编译器开始处理源码之前它就被预处理器移走了。于是记号名称 ASPECT_RATIO 有可能没进入记号表(symbol table)内。于是当你运用此常量但获得一个编译错误信息时,因为这个错误信息也许会提到 1.653 而不是 ASPECT_RATIO。如果 ASPECT_RATIO 被定义在一个非你所写的头文件内,你肯定对 1.653 以及它来自何处毫无概念,于是你将因为追踪它而浪费时间。这个问题也可能出现在记号式调试器( symbolic debugger)中,原因相同:你所使用的名称可能并未进入记号表(symbol table)。
-
使用常量替换 #define
const double AspectRatio = 1.653;
使用
const
后,AspectRatio 作为一个常量,肯定会被编译器看到。使用常量替换 #define 时,有两种需要注意的情况:
-
一是定义常量指针
由于常量定义式通常被放在头文件内(以便被不同的源码含入),因此有必要将指针(而不只是指针所指之物)声明为const。例如若要在头文件内定义一个常量字符串:const std::string authorName("Scott Meyers");
-
二是class专属常量
为了将常量的作用域限制于 class 内,你必须让它成为 class 的一个成员;而为确保此常量至多只有一份实体,你必须让它成为一个 static 成员:class GamePlayer { private: static const int NumTurns = 5; // 常量声明式 int scores[NumTurns]; // 使用常量 ... }
旧式编译器也许不允许在 static 成员声明式上赋初值,因此可将初值放在定义式:
class ConstEstimate{ private: static const double FudgeFactor; // static class常量声明,位于头文件内 ... } const double ConstEstimate::FudgeFactor = 1.35; // static class常量定义,位于实现文件内
假设,若你在 class 编译期间需要一个 class 常量值,例如上面在 GamePlayer 类中给常量赋初值。但旧式编译器不允许在声明时赋初值,因此需要使用枚举(enum),于是 GamePlayer 可定义如下:
class GamePlayer { private: enu { NumTurns = 5 }; // 令NumTurns成为5的一个记号名称 int scores[NuTurns]; }
我们无法对一个 enum 取地址,因此,若你如果你不想让别人获得一个 pointer 或 reference 指向你的某个整数常量,enum 可以帮助你实现这个约束。
-
评论区