#define ASPECT_RATION 1.653
书中说 #define或许不被视为语言的一部分 ASPECT_RATION可能从未被语言看到,这个记号可能未被进入记号表,并且调试的时候错误信息也是1.653,而不是 ASPECT_RATION,如果 ASPECT_RATION被定义在一个非你所写的头文件的话,你肯定对1.653来自哪里,于是你将因为一个非你所写的头文件而浪费时间,这个问题也可能出现在记号式调试器中,原因相同,你所使用的名称未进记号表
当我们以const替换define的时候由两种情况值得说
1 定义常量指针和定义指针所指的常量对象,在c++ primer中称为顶层const和底层const 顶层const表示指针本身是个常量,底层const是指指针所指的对象是个const
int i=10;
int *const p1=&i; //不能改变p1的值,顶层const
const int *p2=&i; //允许改变p2的值,底层const
(顶层const在右边,底层在左边)
所以声明一个指向字符串的常量指针 为 const char * const p="hello,world";
2 关于class的专属常量
class Test
{
private:
static const double number;
};
const double Test::number = 10;
(提起说下,static为什么要类外初始化,因为静态成员属于整个类,而不属于某个对象,如果在类内初始化,会导致每个对象都包含该静态成员,这是矛盾的。在类外初始化不需要加static关键字)
书上说,有的编译器可以支持 static const变量类内初始化,但是我使用的是vs2013不支持,只能在类外初始化,
const double Test::number = 10; 放在实现文件而不是头文件
enum: 如果class编译期间必需要一个常量值的话,并且你的编译器不支持class 的专属常量 在类内设定,比如
这样就会产生错误,这时就可以使用enum
class Test
{
private:
enum { number = 5 };
int arr[number];
};
inline:
我们知道宏替换有太多的缺点 ,比如
#define ONE 1
#define TWO ONE+ONE
在编译中,ONE替换成1没问题,但是TWO替换成了ONE+ONE即1+1
所以如果2*TWO就会变为2*1+1=3
我们期望2*(1+1)=4
所以我们要以inline函数替换这些类型的宏更加的稳妥
总结:
对于单纯的常量的话,最好以const对象或enum替换#define
对于形似函数的宏,最好改用inline替换#define