C ++类头文件组织
什么是C ++编码和文件组织的指导方针,你build议谁必须处理许多相互依赖的类分散在几个源文件和头文件的人?
我在我的项目中有这种情况,解决了类定义相关错误越过了几个头文件变得相当头疼。
一些一般准则:
- 将你的接口与实现配对。 如果你有
foo.cxx
,那里定义的所有东西最好在foo.h
声明。 - 确保每个头文件#包含独立编译所需的所有其他必要头文件或前向声明。
- 抵制创build“一切”标题的诱惑力。 他们总是麻烦在路上。
- 将一组相关(和相互依赖)的function放到一个文件中。 Java和其他环境鼓励每个文件一个类。 使用C ++,您通常需要每个文件的一组类。 这取决于你的代码的结构。
- 只要可能,最好使用
#include
前向声明。 这可以让你打破循环的头文件依赖。 本质上,对于跨单独文件的循环依赖关系,您需要一个如下所示的文件依赖关系图:-
A.cxx
要求Ah
和Bh
-
B.cxx
要求Ah
和Bh
-
Ah
需要Bh
-
Bh
是独立的(并且在Ah
定义了前向声明类)
-
如果您的代码旨在成为其他开发人员使用的库,则需要执行一些重要的附加步骤:
- 如有必要,使用“私人标题”的概念。 也就是说,几个源文件所需的头文件,但公共接口从来不需要。 这可能是一个共同的内联函数,macros或内部常量的文件。
- 在文件系统级别将您的公共接口与私有实现分开。 我倾向于在我的C或C ++项目中使用
include/
和src/
子目录,其中include/
包含我所有的公共头文件,而src/
包含我所有的源文件。 和私人标题。
我build议findJohn Lakos的书“ 大规模C ++软件devise ”的副本。 这是一本相当大的书,但是如果你只是浏览一下他关于物理结构的讨论,那么你会学到很多东西。
查看NASA戈达德太空飞行中心的C和C ++编码标准。 我在C标准中特别注意到的并且在我自己的代码中采用的一个规则是强制实现头文件的“独立”性质。 在头文件xxx.h的实现文件xxx.cpp中,确保xxx.h是包含的第一个头文件。 如果标题在任何时候都不是独立的,那么编译将会失败。 这是一个非常简单而有效的规则。
唯一一次失败的是如果你在机器之间进行端口连接,并且xxx.h头文件包含<pqr.h>
,但是<pqr.h>
需要恰好可以通过头文件<abc.h>
在<pqr.h>
包含<abc.h>
),但是其他平台上的<abc.h>
不能使用这些工具(它们在def.h
,而是在<pqr.h>
不包括<def.h>
)。 这不是规则的错误,如果遵循规则,问题更容易被诊断和修复。
检查Google风格指南中的头文件部分
汤姆的回答非常好!
我唯一要做的就是永远不要在头文件中使用“声明”。 他们应该只允许在实现文件,如foo.cpp
。
这个逻辑在“Accelerated C ++”( 亚马逊链接 – 为脚本kiddie链接纳粹消毒)
除此之外还有一点:
不要在包含文件中包含任何私人定义。 例如,只有在xxx.cpp中使用的任何定义应该在xxx.cpp中,而不是xxx.h中。
看起来很明显,但我经常看到它。
我想添加一个很好的习惯(C和C ++)
foo.c的
#include "foo.h" // always the first directive
任何其他需要的头文件应该遵循,然后代码。 问题是你总是需要这个编译单元的头文件,并且把它作为第一个指令保证头文件是自给自足的(如果不是,将会出现错误)。 公共标题尤其如此。
如果在任何时候你需要在这个头文件之前加上一些东西(当然除了注释),那么很可能你做错了什么。 除非你真的知道你在做什么…这导致另一个更重要的规则=>评论你的黑客!