.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? -------
答案 0 :(得分:25)
cpp
- 文件中包含它。正如@Pedro d'Aquino所评论的那样,你可以尽可能使用前向声明来减少标题中包含的数量(基本上每当你只使用对给定类型的引用或指针时)。答案 1 :(得分:7)
Header file include patterns上的这篇文章对您有所帮助。
- 是否有一些首选的方法来组织包含指令?
是,您可以在上面的文章中找到它们。
- 最好在.cpp文件中包含所需的文件而不是 .h文件?是翻译单位 受某种程度影响?
是,最好将它们放在.cpp中。即使如果在定义另一种类型时需要定义类型,也可以使用前向声明。
- 如果我在.h文件和.cpp文件中都需要它,我应该这样做 将它包含在.h文件中?会吗 事?
仅限于.h文件,但建议在头文件中转发声明,并包含在.cpp文件中。
- 将已定义的文件保留在预编译中是一种好习惯 header(stdafx.h),例如std 和第三方图书馆?怎么样 我自己的文件,我应该包含它们 像我一样的stdafx.h文件 创造它们?
我个人没有使用过预编译的头文件,但早先在Stackoverflow上对它们进行了讨论:
答案 2 :(得分:5)
是否有一些首选方法来组织包含指令?
没有共同的约定。有些人建议对它们进行字母排序,我个人不喜欢它,并且更喜欢将它们保持逻辑分组。
最好在.cpp文件中包含所需的文件而不是.h文件吗?
总的来说,是的。它减少了编译器打开和读取头文件的次数,只是为了查看那里的包含保护。这可能会缩短整体编译时间。 有时,为了同样的原因,有人也建议在标题中向前声明尽可能多的类,并且实际上仅将它们包含在.cpp中。例如,“Qt人”这样做。
翻译单位是否会受到影响?
在语义上,没有。
如果我在.h文件和.cpp文件中都需要它,我应该将它包含在.h文件中吗?这有关系吗?
只需将其包含在标题中即可。
将已定义的文件保存在预编译的头文件(stdafx.h)中,例如std和第三方库,这是一个好习惯吗?我自己的文件怎么样,我应该在创建它们的过程中将它们包含在stdafx.h文件中吗?
预编译头可以显着减少编译时间。例如:我的一个项目包括boost::spirit::qi
在20秒内编译PCH,80秒 - 没有。一般来说,如果你使用像boost
这样的大量模板填充库,你会想要利用PCH的优势。
至于您的代码示例中的问题:,因为您不在标头中使用std :: string,最好将其包含在.cpp
文件中。 #include <string>
stdafx.h
中的{{1}}也没关系 - 但这会给你的项目增加一些复杂性,你几乎不会注意到任何编译加速。
答案 3 :(得分:1)
(4)我不建议在stdafx.h中包含任何其他文件。或类似的“include_first.h”文件。直接包含到cpp或特定的h文件允许您显式表示代码的依赖关系并排除冗余依赖项。当您决定将单个代码分解为几个lib或dll时,它尤其有用。就个人而言,我只使用“include_first.h”(stdafx.h)等文件进行配置(此文件仅包含当前应用程序配置的宏定义)。
通过标记另一个文件来停止预编译而不是stdafx.h,可以为您自己的文件提供预编译的头文件(例如,您可以使用名为“stop_pch.h”的特殊空文件)。
请注意,对于预处理器的某些软件使用情况,预编译头文件可能无法正常工作(特别是对于BOOST_PP_ * 中使用的某些技术)
答案 4 :(得分:1)
从表现的角度来看:
更改stdafx.h中包含的任何头文件将触发新的预编译,因此它取决于代码的“冻结”程度。外部库是stdafx.h包含的典型候选者,但您当然也可以包含自己的库 - 这是基于您期望更改它们的频率的权衡。
此外,使用Microsoft编译器,您可以将它放在每个头文件的顶部:
#pragma once
这允许编译器在第一次出现后完全跳过该文件,从而节省了I / O操作。传统的ifndef / define / endif模式需要在每次包含时打开和解析文件,这当然需要一些时间。它肯定会积累并变得引人注目!
(确保将传统警卫留在那里,以便携带。)
答案 5 :(得分:0)
注意翻译单元中的类顺序必须正确或者某些c ++功能只是被禁用并导致编译时错误可能很重要。
编辑:添加示例:
class A { };
class B { A a; }; // order of classes need to be correct