组织包括
Organize includes
- 是否有一些首选的组织方式包括指令
- 将您需要的文件包括在
.cpp
文件中而不是.h
文件中更好吗?翻译单位是否受到某种影响 - 如果我在
.h
文件和.cpp
文件中都需要它,我应该把它包括在.h
文件中吗?这有关系吗 - 将已经定义的文件保存在预编译头(
stdafx.h
)中(例如std和第三方库)是一种好的做法吗?我自己的文件怎么样?在创建它们的过程中,我应该将它们包含在stdafx.h
文件中吗
// myClass.h
#include <string>
// ^-------- should I include it here? --------
class myClass{
myClass();
~myClass();
int calculation()
};
// myClass.cpp
#include "myClass.h"
#include <string>
// ^-------- or maybe here? --------
[..]
int myClass::calculation(){
std::string someString = "Hello World";
return someString.length();
}
// stdafx.h
#include <string.h>
// ^--------- or perhaps here, and then include stdafx.h everywhere? -------
- 你应该把它们放在文件的顶部,放在一个地方。这是每个人所期望的。此外,对它们进行分组也很有用,例如,首先是所有标准标头,然后是第三方标头(按库分组),然后是您自己的标头。在整个项目中保持此顺序的一致性。它使理解依赖关系变得更加容易。正如@James Kanze所指出的,将声明内容的头放在第一位也很有用。通过这种方式,您可以确保它在首先包含时工作(这意味着它不依赖于任何不包含它自己的包含)
- 保持范围尽可能小,这样头中的更改影响的翻译单位数量就最少。这意味着,只要可能,只将其包含在
cpp
-文件中。正如@Pedro d'Aquino所评论的,您可以通过尽可能使用前向声明来减少标头中的include数量(基本上只要您只使用对给定类型的引用或指针) - 两者都显式比隐式好
- 经过一番阅读,我认为只有当你确信标题不再更改时,你才应该在PCH中包含标题。这适用于所有标准头以及(可能)第三方库。对于你自己的图书馆,你是评判者
这篇关于头文件包含模式的文章应该对您有所帮助。
- 是否有一些首选的组织方式包括指令
是,您可以在上面的文章中找到它们。
- 将需要的文件包括在.cpp文件中而不是.h文件?翻译单位是不知怎么受到了影响
是,最好将它们放在.cpp中。即使在定义另一个类型时需要一个已定义的类型,也可以使用正向声明。
- 如果我在.h文件和.cpp文件中都需要它,我应该只是否将其包含在.h文件中?会吗重要吗
仅在.h文件中,但建议在头文件中转发声明,并包含在.cpp文件中。
- 将已定义的文件保存在预编译文件中是一种好的做法吗标头(stdafx.h),例如std和第三方图书馆?怎么样我自己的文件,我应该把它们包括在内吗一个stdafx.h文件创建它们
我个人没有使用预编译的头文件,但之前在Stackoverflow上已经讨论过它们:
预编译标头?我们真的需要它们吗
是否有一些首选的组织方式包括指令?
没有共同的约定。有些人建议用字母排序,我个人不喜欢,更喜欢按逻辑分组。
将需要的文件包括在.cpp文件中而不是.h文件中更好吗?
总的来说,是的。它减少了编译器打开和读取头文件以查看包含保护的次数。这可能会减少总体编译时间。出于同样的原因,有时还建议在头中转发声明尽可能多的类,并实际上只将它们包含在.cpp中。例如,"Qt人"就是这样做的。
翻译单位是否受到某种影响?
在语义意义上,没有。
如果我在.h文件和.cpp文件中都需要它,我应该把它包括在.h文件中吗?这有关系吗?
只需将其包含在标题中即可。
将已经定义的文件保存在预编译头(stdafx.h)中(例如std和第三方库)是否是一种好的做法?我自己的文件怎么样?在创建它们的过程中,我是否应该将它们包含在stdafx.h文件中?
预编译的标头可以显著减少编译时间。例如:我的一个项目,包括boost::spirit::qi
,在PCH打开的情况下,编译时间为20秒,在没有PCH的情况下编译时间为80秒。一般来说,如果您使用一些像boost
这样的大量填充模板的库,您会希望利用PCH的优势。
至于代码示例中的问题:由于头中没有使用std::string,因此最好将其包含在.cpp
文件中。stdafx.h
中的#include <string>
也可以,但这只会给您的项目增加一点复杂性,您几乎不会注意到任何编译加速。
(4)我不建议在stdafx.h或类似的"include_first.h"文件中包含任何其他文件。直接包含到cpp或特定的h文件中,可以显式地表达代码的依赖关系,并排除多余的依赖关系。当您决定将单片代码分解为几个库或dll时,它尤其有用。就我个人而言,我使用像"include_first.h"(stdafx.h)这样的文件仅用于配置目的(该文件仅包含当前应用程序配置的宏定义)
通过标记另一个文件而不是stdafx.h来停止预编译,可以为自己的文件提供预编译头(例如,可以使用名为"stop_pch.h"的特殊空文件)。
注意,对于预处理器的某些特定用途(特别是BOOST_PP_*中使用的某些技术),预编译的标头可能无法正常工作。
从性能角度来看:
更改stdafx.h中包含的任何头都将触发新的预编译,因此这取决于代码的"冻结"程度。外部库是stdafx.h包含的典型候选库,但您当然也可以包含自己的库-这是一种基于更改频率的折衷。
此外,使用Microsoft编译器,您可以将其放在每个头文件的顶部:
#pragma once
这允许编译器在第一次出现后完全跳过该文件,从而保存I/O操作。传统的ifndef/define/endif模式需要在每次包含文件时打开并解析该文件,这当然需要一些时间。它肯定会积累并变得引人注目!
(为了可移植性,请确保保留传统的保护。)
注意翻译单元中的类顺序需要正确,或者某些c++功能被禁用,从而导致编译时错误,这一点可能很重要。
编辑:添加示例:
class A { };
class B { A a; }; // order of classes need to be correct
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 为什么 cmake 许可证<>样式不包括?
- 计算平均值,不包括上次得分
- 从多个源构造一个对象,包括一个对象向量
- 在编译中包括 Botan 2
- 将值从另一个数组写入数组,不包括不需要的值 C++
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)
- 包括C++头文件
- CPP 包括 Azure DevOps 中的目录设置
- 包括STL,而不会乱扔全球范围
- 如何反转我的输入,包括否定
- 包括没有完整路径的我的库
- 如何在 android ndk 上链接 C 和 C++ 代码,以及 C 和 C++ 运行时库(包括 STL)?
- C++包括类名间距和类实例化
- 链接错误,包括我创建的相同头文件 - C++
- 标头,包括在 Swift 项目中使用C++文件时的错误
- 如果语句不包括文本行?
- 如何将字符串与结构(也包括字符串)进行比较?
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?