在库中使用的最佳头结构是什么?

时间:2009-04-09 16:23:04

标签: c++ header

关于库中的标题,我看到两个选项,我不确定选择是否真的重要。假设我创建了一个库,我们称之为foobar。请帮我选择最合适的选项:

  1. 在库项目的根目录中有一个包含,我们称之为foobar.h,其中包含库中的所有头文件,例如“src / some_namespace / SomeClass.h”等等上。然后从库外部,在我想要使用foobar库的任何文件的文件中,只需#include <foobar.h>

  2. 没有主要包含,而是仅包含我要在其中使用它们的地方所需的标题,因此我可能在源文件中包含一大堆包含。由于我使用的命名空间有时甚至高达3,所以包括标题看起来有点像是一件苦差事。

  3. 我选择了选项1,因为实施起来非常简单。 OpenGL和许多其他库似乎都这样做,所以它似乎合情合理。但是,标准的C ++库可以要求我在任何给定的文件中包含多个头文件,为什么它们只有一个头文件呢?除非是我和白痴,他们是独立的图书馆......

    更新

    除了答案之外,我认为提供这两个选项是正确的,对吗?如果我想使用std :: string但是必须包含大量的头文件,我会非常恼火;那会很傻。另一方面,当我想要使用大部分图书馆时,如果我不得不键入大量的#include行,我会感到恼火。

    转发标头:

    感谢所有向我提供前向标题的建议,这有助于我让丛林丛林变得更加复杂! :)

7 个答案:

答案 0 :(得分:6)

stl,boost和其他拥有大量头文件的人,他们为您提供了独立的工具,您可以单独使用它们。

因此,如果您的库是一组解耦工具,您必须选择将它们作为单独的部分包含在内,并将整个库包含为一个文件。

答案 1 :(得分:5)

想一想你的图书馆将如何使用,并以这种方式组织它。如果有人在不使用整个东西的情况下不太可能使用一个小部件,那么将其构造为一个大的部件。如果一个小部件独立且有用,请确保您可以包含足够的部件。如果有一些合理的逻辑分组,请为每个组创建包含文件。

与大多数编程问题一样,没有一个适合所有人的答案。

答案 2 :(得分:2)

必须处理所有#included标头。这并不像它可能那么糟糕,因为现代编译器提供了某种选择,可以不重复处理它们(可能使用#pragma onceifndef防护等。但是,每个#included标头必须为每个翻译单元处理一次,并且可以快速加起来。

通常的做法是将头文件#include只包含他们需要的头文件,并尽可能使用前向声明(class foo;)。这样,你就不会得到开销。

如果你想#include一切及其兄弟,你可以提供你自己的#includes所有内容的头文件。您不必在每个头文件和源文件中明确写出所有内容。这个选项是你可以提供的,但如果std中的所有内容都是一个整体标题,你就没有选择。

答案 3 :(得分:1)

每当你#include一个头文件时,你就会让编译器做一些非常努力的工作。你#include的标题越少,它所做的工作就越少,你的编辑就越快。

答案 4 :(得分:1)

所有包含文件都应该有自己的意义。你应该从lib-users职位中选择标题结构:用户应该如何使用我的库?什么结构最适合用户?



的示例:
如果你的库提供字符串算法 - 最好用all - string_algorithms.h制作一个标题;
如果您的库提供了一个Facade对象 - 最好使用一个头文件(可能很少有其他带扩展名或助手的文件);
如果你提供将独立使用的复杂对象,则制作不同的头文件(容器lib提供不同的容器);

答案 5 :(得分:1)

Forward declare,而不是一次性包含所有这些头文件,然后在需要时包含。

答案 6 :(得分:1)

但是,您决定为库的公共API提供可用的头文件(一个,几个或某些组合),为私有API至少有一个单独的头是一个好主意。 (无需公开未导出的函数和类的原型或仅用于内部使用的定义。)