19.3.2 头文件

    系统提供的库函数大多是已编译好的二进制文件,为了能对库提供的功能,如函数等进行调用,必须使用头文件来提供接口声明,不必关心内部代码是如何书写的,编译器会自动从库文件中提取相应的代码。

    提示之所以提供的是已编译好的二进制形式,主要是出于版权和保密的需要,不能对外公开。

    同样商业代码公司也可以编写并出售实现特定功能的二进制代码库,用户只要包含其头文件,提供接口声明,便可调用库中功能,至于功能如何实现的,不是用户需要关心的重点,这就是常说的第3方库,这有效促进了业界的产业化。

    另一方面,对自己编写的cpp文件和h文件,将接口声明都放在h文件中有个好处就是省去了对接口的显式声明,因为h文件是在文件开始包含的,因此其中声明的接口对整个文件都是可见的,方便调用,同时头文件能加强类型安全检查,当调用方式和头文件中的声明不一致时,编译器将指出错误。

    对头文件来说,一条重要的原则是只声明,不定义。在头文件中不要出现函数的定义,即使是类的成员函数,虽然可以在声明的同时定义,且自动成为内联形式,但不推荐使用,不论函数体多小,建议将其实现都放在cpp文件中,如果要声明为内联形式,可以使用inline修饰。

    全局变量的使用破坏了程序的封装性,不提倡使用全局变量,如非确实需要,尽量不要在头文件中出现如“extern int g_num”这样的声明。永远不要在头文件中定义变量,定义变量和声明变量的区别在于定义会分配内存,属于编译的范畴,而声明则只是告诉包含该声明的模块再从其他模块中寻找外部函数和变量,属于链接的范畴。

    单独的头文件不参加编译,只有包含在cpp文件中的头文件才辅助该cpp文件完成编译,这便是编译单元(Compile Unit)的概念,关于编译单元的介绍请参考第20章。