命名空间和模块化编程
接下来我们将重点讨论两个相互关联的简单概念:
第一个概念是模块化(modularization)
把程序划分成多个组成部分(即所谓的“模块”)
这是通过把程序代码分散到多个文件里,等编译程序时再把那些文件重新组合在一起实现的。
第二个概念是命名空间(namespace)
这个概念相比起C语言是C++里新增加的东西,编写的程序越多、编写的程序越复杂,就越需要使用命名空间。
头文件
只用一个源代码文件来保存程序的全部代码是可行的,但那会给编辑修改工作带来诸多不便。
我们可以借助于C++的预编译器和编译器的能力把一个复杂的应用程序划分成多个不同的文件,而仍保持它在内容和功能上的完整。
C++预处理器的#include指令提供了一种能够让编译器在编译主程序时把其他文件的内容包括进来的机制。
例如用这个指令来包括像iostream头文件我们已经用过很多次了。
头文件的基本用途是提供必要的函数声明和类声明。比如string头文件就定义了字符串应该如何创建和使用。
头文件可以细分为系统头文件和自定义头文件。
顾名思义,系统头文件定义的都是系统级功能,正式因为有了它们,C++代码才可以在某种特定的系统上运行。
如果你想在你的程序使用这些功能,就必须把相应的头文件包括到你的程序里来。
系统头文件的另一个重要作用是保证C++代码的可移植性,确保同样的C++代码在不同的操作系统上做同样的事情。
例如为Mac定义的cout和为Windows定义的cout做的事情一样,但内部的具体实现不见得一样。
在#include指令里,系统头文件的文件名要放在尖括号里给出,这是告诉编译器:应该到“标准的”地点寻找这个文件:
#include <stdio.h>
创建头文件
在#include指令里,自定义头文件的文件名要放在双引号里给出:#include “fishc.h”
头文件是一些以.h作为扩展名的标准文本文件。
一般情况下,都应该把自定义的头文件和其余的程序文件放在同一个子目录里,或者在主程序目录下专门创建一个子文件夹来集中存放它们。
你可以用头文件来保存程序的任何一段代码,如函数或类的声明,但一定不要用头文件来保存它们的实现!
与标准的C++源代码文件相比,在头文件里应该使用更多的注释。
绝大多数头文件是通用型的,不隶属于任何特定的程序,所以至少把它的用途和用法描述清楚。
应该在注释里说明的内容包括:
创建日期,文件用途,创建者姓名,最后一次修改日期,有什么限制和前提条件等等。
另外头文件里的每一个类和函数也应该有说明。
挖坟并分离头文件出来:Rational (课件及源代码下载)
提示
虽说头文件可以用来保存任意代码片段,但典型的做法是只用它们来保存函数声明、用户自定义类型数据(结构和类)、模板和全局性的常量。
如果你有一个程序需要多次调用一个或一组函数,或是你有一个或一组函数需要在多个程序里调用,就应该把它们的声明拿出来放到一个头文件里。
头文件应该只包含最必要的代码,比如只声明一个类或只包含一组彼此相关的函数。