C++ Primer, 4th edition. page 67. Writing Our Own Header Files
该小节讲了关于头文件的知识。我注意到这句话值得深思,“头文件用作声明,不用作定义,但有3种情况例外。”
书里提到的3种例外情况分别是:
1. 类的定义。
2. 在编译阶段值可以确定的常量。
3. 内联函数。
我想搞清楚的是,为什么这3种情况需要被作为例外。书里给出的解释是编译器在生成源码时,需要用到这些“实体”(entities)的定义,而不仅仅是声明。经过一定的思考,我得到的答案大概如下:
对于类的定义,作者举的例子是,如果有代码需要使用类的成员函数或者定义类时,编译器是需要知道该类的结构的。此外,我想到的是,类的定义与内建类型(Build in Type)不同,类的定义有点儿像声明。因为在你定义类的时候,不是对这个类进行内存的分配,而是告诉编译器该类的结构。与内建类型的定义对应的应该是实例化。
对于常量,作者用了比较长的篇幅进行阐明。其大意为,常量在默认情况下,其作用域不是全局的,而是一个文件,因此,每个源文件包含头文件并不引起multiple definitions error。另外,编译器在实际操作中,也不会对这种常量进行分配内存,而是直接将其用定义时的常量表达式替换掉。
对于内联函数,作者没有提,不过用大腿想想也知道了,和常量类似,都是直接替换。
总结一下,就以我目前所学到的知识来看,声明是必须的。声明的作用是告诉编译器该变量在其它位置有定义。这样的好处在单个源文件里是体现不了,如果在多个源文件中的话,就显得必要了,尤其是C++的编译器需要支持对源文件的单独编译。