c++ - 仅 header 库设计 - 包含指令

标签 c++ c++11 include header-only

我正在创建一个仅包含 header 的 C++11/14 库,但我不确定应该如何处理库文件之间的 #include 指令。

我应该尝试在面向用户的模块头文件中对尽可能多的 #include 指令进行分组,还是内部文件应该包含它们需要的文件(有时重复相同的包含)?


方法一:

在这种方法中,模块头文件包含所有必需的依赖项,然后包含实现。实现的头文件本身不包含任何内容。

// Library/Module/Module.hpp
// This file is intended to be included by the user in his projects.

#ifndef MODULE
#define MODULE

#include <vector>
#include "Library/Module/Impl/SharedDependency.hpp"
#include "Library/Module/Impl/Class1.hpp"
#include "Library/Module/Impl/Class2.hpp"

#endif MODULE

-

// Library/Module/Impl/SharedDependency.hpp

#ifndef SHARED_DEPENDENCY
#define SHARED_DEPENDENCY

inline void sharedFunc() { }

#endif

-

// Library/Module/Impl/Class1.hpp

#ifndef CLASS1
#define CLASS1

// No need to include "SharedDependency.hpp", as it will be included by
// the module header file. Same applies for <vector>.
struct Class1 
{ 
    std::vector<int> v;        
    Class1() { sharedFunc(); } 
};

#endif

-

// Library/Module/Impl/Class2.hpp

#ifndef CLASS2
#define CLASS2

// No need to include "SharedDependency.hpp", as it will be included by
// the module header file. Same applies for <vector>.
struct Class2
{ 
    std::vector<int> v;        
    Class2() { sharedFunc(); } 
};

#endif


方法 B:

在这种方法中,模块头文件仅包含实现头文件。如果实现 header 需要额外的包含,它们会包含文件本身(递归),有时会重复相同的包含。

// Library/Module/Module.hpp
// This file is intended to be included by the user in his projects.

#ifndef MODULE
#define MODULE

#include "Library/Module/Impl/Class1.hpp"
#include "Library/Module/Impl/Class2.hpp"

#endif MODULE

-

// Library/Module/Impl/SharedDependency.hpp

#ifndef SHARED_DEPENDENCY
#define SHARED_DEPENDENCY

inline void sharedFunc() { }

#endif

-

// Library/Module/Impl/Class1.hpp

#ifndef CLASS1
#define CLASS1

#include <vector>
#include "Library/Module/Impl/SharedDependency.hpp"

struct Class1
{ 
    std::vector<int> v;        
    Class1() { sharedFunc(); } 
};

#endif

-

// Library/Module/Impl/Class2.hpp

#ifndef CLASS2
#define CLASS2

#include <vector>
#include "Library/Module/Impl/SharedDependency.hpp"

struct Class2
{ 
    std::vector<int> v;        
    Class2() { sharedFunc(); } 
};

#endif

什么是最好的方法?

直觉上,我认为方法 A 是最好的,因为它避免了重复相同的包含,并明确了在其他文件之前需要包含哪些文件。不过,最大的缺点是语法高亮显示在我的 IDE (QT-Creator) 中停止工作,在没有 include 指令的实现文件中。


编辑:

由于“基于意见”,这个问题被投票关闭。我不同意,因为在像我的包含文件的库这样的大型仅 header 项目中,可能需要很多编译时间。因此,方法 A 可能比方法 B 更快,反之亦然。

最佳答案

方法 B 实际上是最好的方法,因为多次包含相同的 header 不会产生任何可观察到的编译时间增加,但由于以下原因是有利的:

  • 现代 IDE 可以使用 libclang 或专有解决方案来解析 #include 指令并提供代码感知语法突出显示和自动完成功能。

  • 正如 TemplateRex 所提到的,验证一个健全的构建过程变得更加容易。例如,CMake 提供了为每个 header 自动生成测试的宏。

  • 正如 Alf 所提到的,让每个文件都包含它所依赖的所有头文件是一种很好的做法 - 然后库的用户可以“挑选”他们需要的头文件,而不是意外地强制手动包含一个父标题。

关于c++ - 仅 header 库设计 - 包含指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23765511/

相关文章:

c++ - 这个 constexpr 虚函数技术是否违反了任何 C++11/C++14 规则?

c++ - 如果没有直接包含h文件如何给出警告

php - 名称数组 = 获取正确的文件

c++ - 使用 sc create 启动时 Windows 程序不运行

c++ - 在 C++ Builder 2010 中构建 shockwave ActiveX(Flash) 时的几个错误

c++ - Doxygen 与 Qt 定义

c++ - 在 for 循环中使用 end() 时无法访问双向链表中的最后一个元素

c++ - 使用 '&'进行迭代时 'auto'符号有什么作用

php - 如何在 php/smarty 中包含静态 html

c++ - 如何在类里面正确使用 boost channel (和光纤)?