1.const替代#define
#define ASPECT_RATIO 1.65
记号名称ASPECT_RATIO从未被编译器看见,所以在记号表可能看不到该记号,所以当你运用该常量发生一个编译错误时,可能会带来疑惑,因为该错误信息只会提到1.65而不是ASPECT_RATIO,如果该定义是在一个非你所写的头文件里,你肯定对1.65以及它来自何处没有概念,于是你将因为追踪它而浪费时间。
解决:
const double AspectRatio =1.65;
作为一个语言常量,AspectRatio肯定会被编译器看到,当然就会进入记号表内。
指针常量:是一个常量,指针是修饰常量的,表示常量值为一个指针,因为是常量,所以声明时必须初始化。虽然是常量,但是不代表指针指向的值就是常量,所以指针指向的值是可以改变的。
int a;
char* const b =&a;(const放在指针声明操作符的右侧)
常量指针:是一个指针,常量是修饰指针的,表示不可以通过指针修改指针指向的值,但是!不代表指针指向的值就是常量,所以指针指向的值是可以改变的。
const int* p;
int const* p;
指向常量的指针常量:是一个常量,而且指向的对象也是一个常量
const int a =25;:
const int *const b=&a;
2.使用enum
class GamePlayer
{
private:
static const int NumTurns=5;
int scores[NumTurns];
...
};
然而你所看到的是NumTurns的声明式而非定义式。通常C++要求你对你所使用的任何东西提供一个定义式。
const int GamePlays::NumTurns;
问题来了:旧式编译器不支持上述语法,它们不允许static成员在其声明式上获得初始值。
那只能:
class ConstEstimate
{
static const double FudgeFactor;
...
}
const double ConstEstimate:: FudegeFactor=1.35;
那问题又来了,当你需要class编译期间需要一个class常量值,例如上述的GamePlayer::scores的数组声明式中,编译器坚持必须在编译期间知道数组的大小。
解决:使用enum
class GamePlayer
{
private:
enum{NumTurns=5};
int scores[NumTurns];
...
}
如果你不想让别人用一个指针或引用 指向你的某个整数常量,enum可以帮你实现这个约束。
3.使用inline代替#define
#define CALL_WITH_MAX (a,b) f((a) > (b) ? (a) :(b));
int a=5,b=0;
CALL_WITH_MAX(++a,b); //a被累加两次
CALL_WITH_MAX(++a,b+10;//a被累加一次
解决:
template<typename T>
inline void callWithMax(const T &a, const T &b)
{
f(a>b?a:b);
}
这里不需要在函数本体中为参数加上括号,也不需要担心参数被核算多次。