头文件卫哨
每个头文件一般会包含卫哨,即下面的定义:
//foo.h
#ifndef FOO_H
#define FOO_H
#endif
另外还有一种卫哨称为包含卫哨,如:
//foo.h
#ifndef FOO_H
#define FOO_H
#ifndef TOOLS_H
#include "tools.h"
#endif
#endif
通过包含卫哨,即使不修改其它代码,也能大大节省编译时间。
物理依赖
在物理依赖中,组件是最小单位,一个组件包含一个.h和.c文件。关系紧密的逻辑组件应当包含在一个组件中。
通过头文件的包含关系,可以推导出整个工程的物理依赖,但有些情况下会导致隐含依赖。
比如在.c文件中使用extern声明外部变量会导致隐式依赖另外一个物理组件,更坏的是,如果原来的函数声明变了,extern声明没有变,会导致错误。所以应该用头文件包含替代这种extern的方式。
在.c文件中,应该把对应的.h文件放在包含的第一位,这样可以发现未声明的依赖,如果客户组件包含一些头文件时发现必须遵守一定顺序,通常有这种问题。
例如:
//foo.c
#include <iostream>
#include "foo.h"
ostream& operator<<(ostream& , foo& );
//test.c
#include "foo.h"
#include <iostream>
这时test.c就有可能编译通不过,如果foo.h没有包含iostream的话,如果在foo.c中把foo.h包含放在第一个,很容易发现这种问题。
依赖是可以传递的。
isA和hasA必然导致物理依赖,use和HoldsA(包含指针或引用)可能导致物理依赖。