7.1.1 头文件里的const
与使用#define一样,使用const必须把const定义放进头文件里。这样,通过包含头文件,
可把const定义单独放在一个地方并把它分配给一个编译单元。C+ +中的const默认为内部连接,
也就是说,c o n s t仅在c o n s t被定义过的文件里才是可见的,而在连接时不能被其他编译单元看
到。当定义一个常量(c o n s t)时,必须赋一个值给它,除非用e x t e r n作了清楚的说明:
extern const bufsize;
虽然上面的e x t e r n强制进行了存储空间分配(另外还有一些情况,如取一个c o n s t的地址,也要
进行存储空间分配),
但是C + +编译器通常并不为c o n s t分配存储空间,相反它把这个定义保存
在它的符号表里。当c o n s t被使用时,它在编译时会进行常量折叠。
当然,绝对不为任何c o n s t分配存储是不可能的,尤其对于复杂的结构。这种情况下,编译
器建立存储,这会阻止常量折叠。这就是c o n s t为什么必须默认内部连接,即连接仅在特别编
译单元内的原因;否则,由于众多的c o n s t在多个c p p文件内分配存储,容易引起连接错误,连
接程序在多个对象文件里看到同样的定义就会“抱怨”了。然而,因为c o n s t默认内部连接,
所以连接程序不会跨过编译单元连接那些定义,因此不会有冲突。对于在大量场合使用的内部
数据类型,包括常量表达式,编译器都能执行常量折叠。
7.1.4 与C语言的区别
常量引进是在早期的C + +版本中,当时标准C规范正在制订。那时,常量被看作是一个好
的思想而被包含在C中。但是,C中的c o n s t意思是“一个不能被改变的普通变量”,在C中,它
总是占用存储而且它的名字是全局符。C编译器不能把c o n s t看成一个编译期间的常量。在C中,
如果写:
const bufsize=100;
char buf[bufsize];
尽管看起来好像做了一件合理的事,但这将得到一个错误结果。因为b u f s i z e占用存储的某个地
方,所以C编译器不知道它在编译时的值。在C语言中可以选择这样书写:
const bufsize;
这样写在C + +中是不对的,而C编译器则把它作为一个声明,这个声明指明在别的地方有存储
分配。因为C默认c o n s t是外部连接的,C + +默认c o n s t是内部连接的,这样,如果在C + +中想完
成与C中同样的事情,必须用e x t e r n把连接改成外部连接:
extern const bufsize;//declaration only
这种方法也可用在C语言中。
在C语言中使用限定符c o n s t不是很有用,即使是在常数表达式里(必须在编译期间被求出)
想使用一个已命名的值,使用c o n s t也不是很有用的。C迫使程序员在预处理器里使用# d e f i n e。