C ++类头文件组织

时间:2008-12-06 07:35:20

标签: c++ class file header organization

对于必须处理分布在多个源文件和头文件中的大量相互依赖类的人,您建议使用哪些C ++编码和文件组织指南?

我在我的项目中遇到这种情况,解决跨越几个头文件的类定义相关错误已经变得非常头疼。

6 个答案:

答案 0 :(得分:66)

一些一般性指导原则:

  • 将接口与实现配对。如果您有foo.cxx,则最好在foo.h中声明所有内容。
  • 确保每个头文件#包含独立编译所需的所有其他必要的头文件或前向声明。
  • 抵制创造“一切”标题的诱惑。他们总是遇到麻烦。
  • 将一组相关(且相互依赖)的功能放入单个文件中。 Java和其他环境鼓励每个文件一个类。使用C ++,您经常需要每个文件有一个类。这取决于代码的结构。
  • 尽可能优先于#include发出声明。这允许您打破循环标头依赖项。本质上,对于跨单独文件的循环依赖,您需要一个类似于下面的文件依赖图:
    • A.cxx需要A.hB.h
    • B.cxx需要A.hB.h
    • A.h需要B.h
    • B.h是独立的(以及A.h中定义的前向声明类)

如果您的代码旨在成为其他开发人员使用的库,则还需要执行一些其他重要步骤:

  • 如有必要,请使用“私有标题”的概念。也就是说,几个源文件需要的头文件,但公共接口从不需要。这可以是具有公共内联函数,宏或内部常量的文件。
  • 在文件系统级别将公共接口与私有实现分开。我倾向于在我的C或C ++项目中使用include/src/子目录,其中include/包含我的所有公共标题,src/包含我的所有来源。和私人标题。

我建议找一本John Lakos的书大型C ++软件设计。这是一本非常沉重的书,但是如果你只是略过一些关于物理架构的讨论,你会学到很多东西。

答案 1 :(得分:8)

NASA Goddard Space Flight Center查看C和C ++编码标准。我在C标准中特别注意并在我自己的代码中采用的一条规则是强制执行头文件的“独立”性质的规则。在头文件xxx.h的实现文件xxx.cpp中,确保xxx.h是包含的第一个头。如果标头在任何时候都不是自包含的,则编译将失败。这是一个非常简单而有效的规则。

它失败的唯一一次是你在机器之间移植,而xxx.h标头包括,例如<pqr.h>,但是<pqr.h>需要碰巧由标头提供的设施{原始平台上的{1}} {<abc.h>包括<pqr.h>},但<abc.h>在其他平台上无法使用这些工具(它们位于<abc.h>中,但def.h不包含<pqr.h>)。这不是规则的错误,如果您遵循规则,问题就更容易诊断和修复。

答案 2 :(得分:6)

检查Google style guide

中的标题文件部分

答案 3 :(得分:5)

Tom's answer非常棒!

我唯一要补充的是永远不会在头文件中使用“声明”。它们只应该被允许在实现文件中,例如foo.cpp

这本书的逻辑在优秀的书籍“Accelerated C ++”(Amazon link - 为脚本小子链接纳粹消毒了)中有详细描述。

答案 4 :(得分:3)

除此之外还有一点:

  

不要包含任何私人定义   在包含文件中。例如。任何   仅用于的定义   xxx.cpp应该在xxx.cpp中,而不是   xxx.h.

看起来很明显,但我明白了 频繁。

答案 5 :(得分:3)

我想添加一个非常好的练习(在C和C ++中),这经常被抛弃:

foo.c的

#include "foo.h" // always the first directive

应该遵循任何其他所需的标题,然后是代码。关键是你几乎总是需要这个编译单元的头,并且包括它作为第一个指令保证头保持自给自足(如果不是,将会有错误)。对于公共标题尤其如此。

如果在任何时候你需要在这个标题包含之前添加一些东西(当然除了评论),那么很可能你做错了。除非你真的知道你在做什么......这导致另一个更重要的规则=&gt;评论你的黑客!