当使用#define时: #define AS 1.65
记号名称AS从未被编译器看见,若运行此常量得到一个编译错误信息时,这个错误信息提到1.65而不是AS.
解决方法是:用一个常量替换宏(#define): const double AS = 1.65;
作为语言常量,AS肯定会被编译器看到,当然就会进入记号表.
以常量替换#define两种特殊情况: 1.定义常量指针,有必要将指针const。若要定义一个常量字符串,必须写const两次: const char* const authorName = "amoscykl";
上述的authorName往往如下定义比较好: const std::string authorName("amoscykl");
2.定义class专属常量:将常量的作用域限制于class内,必须让它成为class的一个成员。为了确保此常量唯一,必须让它成为一个static成员: class GamePlayer {
private:
static const int NumTurns = 5; //常量声明式
int scores[NumTurns]; //使用常量
}
无法利用#define创建一个class专属常量。一但宏被定义,它就在其后的编译过程中有效。这就意味着#define不仅不能够用来定义class专属常量,也不能够提供任何封装性,所以没有private #define 这样的东西。const成员变量是可以被封装的。
若编译器不允许"static整数型class常量” 完成"in class初值设定“,可改用"the enum hack”补偿做法。 即枚举类型的数值可充int使用: class GamePlayer {
private:
enum { NumTurns = 5 }; //"the enum hack"-令NumTurns成为5的记号名称
int scores[NumTurns];
}
再看以下例子: #define MAX(a,b) ((a) > (b) ? (a) : (b))
int main()
{
int a = 5, b = 0;
MAX(++a,b); //a被累加两次
MAX(++a,b+10); //a被累加一次
return 0;
}
当写出这种类似函数的宏,必须为所有实参加上小括号. 第一个MAX, 因为a > b, 所以f返回a, ++a作为实参被调用两次,所以累加两次. 第二个MAX, 因为a <b,所以 f 返回 b , ++a作为实参被调用一次,所以只累加一次 在调用f之前,a的递增次数居然取决于和谁作比较!
解决办法:template inline函数,既可以获得宏带来的效率以及一般函数的所有可预料行为和类型安全性. template<typename T>
inline void callwithmax(const T& a, const T& b) //T采用pass by reference-to-const
{
a > b ? a : b;
}
这个template产生一整群函数,每个函数接受两个同型对象,并以其中较大者调用f.不需要在
总结: 1.对于单纯常量,最好以const对象或enums替换#define 2.对于形似函数的宏,最好改用inline函数替换#define
|