C++ 在头文件与源文件中包含 #includes
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2596449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Including #includes in header file vs source file
提问by Rob from Utah
I like to put all my #includes in my header file then only include my header for that source file in my source file. What is the industry standard? Are there any draw backs to my method?
我喜欢把我所有的#includes 放在我的头文件中,然后只在我的源文件中包含我的源文件的头文件。什么是行业标准?我的方法有什么缺点吗?
回答by tzaman
Generally, you only want to put the minimum necessary includes into a class header file, as anyone else who uses that header will be forced to #include
all of them too. In larger projects, this leads towards slower builds, dependency issues, and all sorts of other nastiness.
通常,您只想将最少的必要包含放入类头文件中,因为使用该头文件的任何其他人也将被迫使用#include
所有这些头文件。在较大的项目中,这会导致构建速度变慢、依赖性问题和各种其他问题。
Think of a header file as the public interface to your class. You don't want to saddle everyone who uses it with extra dependencies, unless they're necessaryto be able to use the class.
将头文件视为类的公共接口。您不想让使用它的每个人都具有额外的依赖项,除非他们必须能够使用该类。
Move anything that's only needed in the class implementation down into the source file. For other classes used in a header, only #include
their headers if you actually need to know their size or contents in the header- anything else and a forward declarationis sufficient. Most cases, you only need to #include
classes you're inheriting from, and classes whose objects are value members of your class.
将仅在类实现中需要的任何内容下移到源文件中。对于标题中使用的其他类,#include
如果您确实需要知道它们的大小或标题中的内容,则只有它们的标题- 任何其他内容和前向声明就足够了。大多数情况下,您只需要#include
继承自的类,以及其对象是您的类的值成员的类。
This pagehas a good summary. (Replicated below for reference)
这个页面有一个很好的总结。(以下复制以供参考)
C++ Header File Include Patterns #
C++ 头文件包含模式 #
Large software projects require a careful header file management even when programming in C. When developers move to C++, header file management becomes even more complex and time consuming. Here we present a few header file inclusion patterns that will simplify this chore.
即使在使用 C 编程时,大型软件项目也需要仔细的头文件管理。当开发人员转向 C++ 时,头文件管理变得更加复杂和耗时。在这里,我们展示了一些头文件包含模式,可以简化这项工作。
Header File Inclusion Rules
头文件包含规则
Here, we discuss the basic rules of C++ header file inclusion needed to simplify header file management.
在这里,我们讨论简化头文件管理所需的 C++ 头文件包含的基本规则。
A header file should be included only when a forward declaration would not do the job.
The header file should be so designed that the order of header file inclusion is not important.
This is achieved by making sure that x.h
is the first header file in x.cpp
The header file inclusion mechanism should be tolerant to duplicate header file inclusions.
The following sections will explain these rules with the help of an example.
仅当前向声明无法完成这项工作时,才应包含头文件。头文件的设计应该使头文件的包含顺序不重要。这是通过确保
头文件包含机制应该容忍重复的头文件包含中x.h
的第一个头文件来实现的x.cpp
。以下部分将通过示例来解释这些规则。
Header File Inclusion Example
头文件包含示例
The following example illustrates different types of dependencies. Assume a class A with code stored in a.cpp
and a.h
.
以下示例说明了不同类型的依赖项。假设一个类 A 的代码存储在a.cpp
和 中a.h
。
a.h
a.h
#ifndef _a_h_included_
#define _a_h_included_
#include "abase.h"
#include "b.h"
// Forward Declarations
class C;
class D;
class A : public ABase
{
B m_b;
C *m_c;
D *m_d;
public:
void SetC(C *c);
C *GetC() const;
void ModifyD(D *d);
};
#endif
a.cpp
a.cpp
#include "a.h"
#include "d.h"
void A::SetC(C* c)
{
m_c = c;
}
C* A::GetC() const
{
return m_c;
}
void A::ModifyD(D* d)
{
d->SetX(0);
d->SetY(0);
m_d = d;
}
File Inclusion Analysis
文件包含分析
Lets analyze the header file inclusions, from the point of view of classes involved in this example, i.e. ABase
, A
, B
, C
and D
.
让分析头文件夹杂物,从所涉及在该示例中的类,即,点ABase
,A
,B
,C
和D
。
- Class ABase:
ABase
is the base class, so the class declaration is required to complete the class declaration. The compiler needs to know the size ofABase
to determine the total size ofA
. In this caseabase.h
should be included explicitly ina.h
. - Class B:Class
A
contains ClassB
by value , so the class declaration is required to complete the class declaration. The compiler needs to know the size of B to determine the total size ofA
. In this caseb.h
should be included explicitly ina.h
. - Class C:
Class C
is included only as a pointer reference. The size or actual content ofC
are not important toa.h
ora.cpp
. Thus only a forward declaration has been included ina.h
. Notice thatc.h
has not been included in eithera.h
ora.cpp
. - Class D: Class
D
is just used as a pointer reference ina.h
. Thus a forward declaration is sufficient. Buta.cpp
uses classD
in substance so it explicitly includesd.h
.
- Class ABase:
ABase
是基类,所以需要类声明来完成类声明。编译器需要知道 的大小ABase
来确定 的总大小A
。在这种情况下,abase.h
应明确包含在a.h
. - Class B:Class
A
包含 ClassB
by value ,所以需要类声明来完成类声明。编译器需要知道 B 的大小来确定A
. 在这种情况下,b.h
应明确包含在a.h
. - C 类:
Class C
仅作为指针引用包含在内。的大小或实际内容C
对a.h
或不重要a.cpp
。因此,仅包含一个前向声明a.h
。请注意,c.h
未包含在a.h
或 中a.cpp
。 - 类 D:类
D
在a.h
. 因此,预先声明就足够了。但实质上a.cpp
使用类D
,因此它明确包含d.h
.
Key Points
关键点
Header files should be included only when a forward declaration will not do the job. By not including c.h
and d.h
other clients of class A
never have to worry about c.h
and d.h
unless they use class C and D by value.
a.h
has been included as the first header file in a.cpp
This will make sure that a.h
does not expect a certain header files to be included before a.h
. As a.h
has been included as the first file, successful compilation of a.cpp
will ensure that a.h
does not expect any other header file to be included before a.h
.
If this is followed for all classes, (i.e. x.cpp
always includes x.h
as the first header) there will be no dependency on header file inclusion.
a.h
includes the check on preprocessor definition of symbol _a_h_included_
. This makes it tolerant to duplicate inclusions of a.h
.
仅当前向声明不起作用时才应包含头文件。通过不包括c.h
和d.h
其他类的客户A
永远不必担心c.h
并且d.h
除非他们按值使用类 C 和 D。
a.h
已经作为第一个头文件包含在a.cpp
这将确保a.h
不期望某个头文件被包含在之前a.h
。由于a.h
已作为第一个文件被包含,成功编译a.cpp
将确保a.h
在a.h
. 如果所有类都遵循这一点(即x.cpp
始终包含x.h
作为第一个头文件),则将不依赖于头文件包含。
a.h
包括检查符号的预处理器定义_a_h_included_
。这使得它可以容忍 的重复包含a.h
。
Cyclic Dependency
循环依赖
Cyclic dependency exists between class X
and Y
in the following example. This dependency is handled by using forward declarations.
在类X
和Y
以下示例之间存在循环依赖。这种依赖是通过使用前向声明来处理的。
x.h and y.h
x.h and y.h
/* ====== x.h ====== */
// Forward declaration of Y for cyclic dependency
class Y;
class X
{
Y *m_y;
...
};
/* ====== y.h ====== */
// Forward declaration of X for cyclic dependency
class X;
class Y
{
X *m_x;
...
};