繁体   English   中英

包括头文件样式 - C ++

[英]Including header files style - C++

我有一个具有以下目录结构的项目。

root
--include
----module1
----module2
--src
----module1
----module2

所以一个文件说src/module1 foo.cpp中的foo.cpp必须包括像,

#include "../../include/module1/foo.hpp"

这看起来很混乱,很难写。 我发现写作包括喜欢

#include <module1/foo.h>

并且在编译看起来很整洁时提供包含文件搜索路径到root/include 但是,我不确定这种风格有任何缺点。

您更喜欢哪一个?为什么? 你也看到以上述方式组织文件有什么问题吗?

#include "../../include/module1/foo.hpp"

应尽可能避免指定路径。 编译器为您提供了更清晰的替代方案。 此外,干净的设计应该确保您不需要处理包含标题的相对路径。

可以从标准中更好地了解使用哪一个(包括使用引号还是尖括号)。

从我的C ++草案副本:

16.2源文件包含

2表单的预处理指令

#include <h-char-sequence> new-line`

搜索一系列实现定义的位置,以查找由<>分隔符之间的指定序列唯一标识的标头,并使标头的整个内容替换该指令。 如何指定场所或标识的头是实现定义的。

3表单的预处理指令

# include "q-char-sequence" new-line 

导致由“delimiters”之间的指定序列标识的源文件的全部内容替换该指令。以实现定义的方式搜索指定的源文件。如果不支持此搜索,或者搜索失败,该指令被重新处理,就像它读取一样

#include <h-char-sequence> new-line`

使用原始指令中相同的包含序列(包括>字符,如果有的话)。

7虽然实现可以提供一种机制来使任意源文件可用于<>搜索,但一般来说程序员应该使用<>表单作为实现提供的头文件,并使用“”表单来实现控制之外的源。

我支持两种风格......用于不同的用途

我们假设您的示例中还有一个目录root/src/common

// in src/module1/foo.cpp
#include "module1/foo.h"

#include "../common/stringProcessing.h"

包括

我不喜欢看到'include'目录,因为当然说找到确切的头文件更难...但是当你开始并转向多个独立库时你需要抽象,因为你希望能够在不改变代码的情况下移动各种组件,我都是为了保持一致性。

此外,使用'..'总是存在风险,因为向后遍历的符号链接,它不会出现在你想到的地方:/

资源

有时您的标头不是公共的,因此不在include目录中。 这些通常用于与您的客户无关的实施细节。 对于那些我使用..如果需要和精确的确切位置。

这允许: - 不要将-Isrc所有可能目录src - 在源代码中轻松找到文件 - 轻松测试源代码之间的依赖关系(grep for ..

杂项

如果我要打字

#include "module/foo.h"

然后我希望使用:

module::Foo myClass;

这使得将一种特定类型与一个特定模块匹配变得容易。

要求一个库 - 一个名称相同的命名空间,可以很容易地导航我们工作的一些~300或~400个组件:我们需要通过某种方式来组织它们!

这意味着您的初始布局会被重新设计为(对于module项目):

root
-- include
---- module
------ part1
------ part2
-- src
---- part1
---- part2

然后使用以下指令: -I/path../root/include我希望您创建libmodule.so库或module二进制文件。

我更喜欢第二种方式

#include <module1/foo.h>

我发现它使源更易于查看。 问题是,当其他人来看你的代码时,它不一定是头文件所在的固有位置,而包含的第一种方式是。

每种风格都有一些缺点,但我更喜欢你指定的风格。 包含路径不得包含任何向上相关性(例如../.. ),并且必须指定它所依赖的模块。

作为一个小改进,我建议你允许module1中的cc文件直接访问他们的.h文件:

module1/%.cc: -I $ROOT/includes/module1

或类似的。 这将在您的c文件中创建一个视觉效果,区分外部包含和默认包括:

// module1/abc.cc
#include <abc.h>
#include <module2/def.h>

Google的C ++风格指南中有一介绍了包含的排序和命名。 它基本上同意到目前为止在其他答案中所说的内容,但值得一看,因为它非常具体。

我更喜欢(和Google同意)在include指令中没有使用..的相对路径。 您初步评估它看起来整洁是正确的。 拥有冗长,笨重的相对路径会使事情更难阅读,更难以重构。 我认为你的方法是正确的。

至于将源文件和包含文件分成两个不同的子树:为什么不将源头文件放在源文件旁边? 它使它们更容易匹配。 除非你希望其他项目使用你的标题,只是链接到你的二进制文件,我想。
<耸肩/>

我不在#include指令中使用路径。 根据我的经验,它们总是在维护阶段引起问题。 许多编译器允许您为头文件指定搜索树。

文件可以移动

他们会的。 您的层次结构将会改变 您可能希望将文件放在不同的驱动器上。 当其他用户修改您的代码时,他们可能会更改位置。 当文件移植到另一个项目时,文件可能会移动。 没有什么能阻止您的文件移动。

在不修改文件的情况下移动文件

知道文件将移动,如果路径在文件中,则移动文件时必须修改该文件。 如果没有文件中的路径,则只需要更改构建指令。 对于大型项目,修改许多文件很麻烦(即使使用脚本)。

在我看来, #include指令中的路径是邪恶的。 执行此操作的人员应接受再培训或发送给其他公司。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM