我应该按照什么顺序包含头文件?
我是编程新手,在我开始使用大量头文件后,头文件的主题让我陷入了困境。除此之外,我正在尝试使用预编译头。我还使用 SFML 库,因此我还必须包含那些标头。
现在我有 stdafx.h、main.cpp,然后是 Ah、A.cpp、Bh、B.cpp、Ch、C.cpp、Dh 和 D.cpp 中包含的类 A、B、C 和 D。
我将按什么顺序在所有文件中包含标头
- 如果所有类都包含 SFML 类的实例
- ,类 D 包含类 A 的实例,类 C
- 包含类 B 的实例, 我的代码:(注意:所有标头都有标头保护)
stdafx.h:
#include <SFML/Graphics.hpp>
#include <iostream>
Ah
#include "stdafx.h"
class A
{
//sfml class
};
A.cpp
#include "stdafx.h"
#include "A.h"
B.h
#include "stdafx.h"
class B
{
//sfml class
};
B.cpp
#include "stdafx.h"
#include "B.h"
C.h
#include "B.h"
class C: public B
{
};
C.cpp
#include "stdafx.h"
#include "C.h"
D.h
#include "A.h"
#include "C.h"
class D
{
A a;
C C; // if left uncommented I recieve a '1 unresolved externals' error
//sfml class
}
D.cpp
#include "stdafx.h"
#include "D.h"
main.cpp
#include "stdafx.h"
#include "D.h"
I'm new to programming and the topic of header files is sort of bogging me down after I started using a lot of them. In addition to that I'm trying to use precompiled headers. I'm also using the SFML library so I have those headers that also have to be included.
Right now I have stdafx.h, main.cpp, then classes A, B, C, and D contained within A.h, A.cpp, B.h, B.cpp, C.h, C.cpp, D.h, and D.cpp.
What order would I go about including the headers in all files if
- all classes contain an instance of an SFML class
- class D contains an instance of class A and class C
- class C contains an instance of class B
My code: (note: all headers have header guards)
stdafx.h:
#include <SFML/Graphics.hpp>
#include <iostream>
A.h
#include "stdafx.h"
class A
{
//sfml class
};
A.cpp
#include "stdafx.h"
#include "A.h"
B.h
#include "stdafx.h"
class B
{
//sfml class
};
B.cpp
#include "stdafx.h"
#include "B.h"
C.h
#include "B.h"
class C: public B
{
};
C.cpp
#include "stdafx.h"
#include "C.h"
D.h
#include "A.h"
#include "C.h"
class D
{
A a;
C C; // if left uncommented I recieve a '1 unresolved externals' error
//sfml class
}
D.cpp
#include "stdafx.h"
#include "D.h"
main.cpp
#include "stdafx.h"
#include "D.h"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我的理念是,在编写良好的代码中,头文件应该包含它们所依赖的所有其他头文件。我的理由是,不应该包含头文件并因此而出现编译器错误。因此,每个头文件应该(在
#ifdef
或#pragma Once
之后 包含防护)包含它所依赖的所有其他标头。为了非正式地测试您是否记得在头文件中包含正确的头文件,*.cpp 文件应该 #include 应该起作用的最小头文件集。因此,如果
A
、B
、C
和D
有单独的头文件,并且您的 cpp 文件使用类D
,那么它应该只包含Dh。不应产生编译器错误,因为 Dh#include
为 Ah 和 Ch、Ch > 包括 Bh,Ah 和 Bh 包括 SFML 标头(无论是什么)。如果合适的话,Ch 和 Dh 可以包含 SFML 标头,但如果您可以确定依赖项 (Bh和啊)已经包含了它。然而,Visual C++ 的“预编译头”方式搞砸了这个逻辑。它要求您将
“StdAfx.h”
包含为第一个头文件,这导致许多开发人员简单地将所有#include
放在整个项目都放在 StdAfx.h 中,并且不要在任何其他头文件中使用#include
。我不推荐这个。或者,他们会将所有外部依赖项放在 StdAfx.h 中(例如 windows.h、boost 标头)并在其他地方#include 本地依赖项,以便更改单个头文件不一定会导致整个项目重建。按照我编写代码的方式,我的大多数 CPP 文件都包含 StdAfx.h 和相应的 .H 文件。因此,A.cpp 包括 StdAfx.h 和 Ah,B.cpp 包括 StdAfx.h 和 Bh,依此类推。 cpp 文件中放置的唯一其他
#include
是头文件未公开的“内部”依赖项。例如,如果类A
调用printf()
,则 A.cpp(不是 Ah)将#include
,因为 Ah 不依赖于 stdio.h。如果您遵循这些规则,那么您的
#include
标头并不重要(除非您使用预编译标头:那么预编译标头在每个 cpp 文件中排在第一位,但不会不需要从头文件中包含)。My philosophy is that in well-written code, header files should include all other header files that they depend on. My reasoning is that it should not be possible to include a header file and get a compiler error for doing so. Therefore, each header file should (after the
#ifdef
or#pragma once
include guard) include all other headers it depends on.In order to informally test that you've remembered to include the right headers in your header files, *.cpp files should #include the minimum set of header files that should work. Therefore, if there are separate header files for
A
,B
,C
andD
, and your cpp file uses classD
, then it should only include D.h. No compiler errors should result, because D.h#include
s A.h and C.h, C.h includes B.h, and A.h and B.h include the SFML header (whatever that is). C.h and D.h can include the SFML header if it seems appropriate, but it's not really necessary, if you can be sure that the dependencies (B.h and A.h) already included it.The way Visual C++ does "precompiled headers" screws up this logic, however. It requires you to include
"StdAfx.h"
as the very first header file, which causes many developers to simply put all#include
s for the entire project in StdAfx.h, and not to use#include
in any of the other header files. I don't recommend this. Or, they will put all external dependencies in StdAfx.h (e.g. windows.h, boost headers) and #include the local dependencies elsewhere so that changing a single header file does not necessarily cause the entire project to rebuild.The way I write my code, most of my CPP files include StdAfx.h, and the corresponding .H file. So A.cpp includes StdAfx.h and A.h, B.cpp includes StdAfx.h and B.h, and so forth. The only other
#include
s placed in a cpp file are "internal" dependencies that are not exposed by the header file. For example, if classA
callsprintf()
, then A.cpp (not A.h) would#include <stdio.h>
, because A.h does not depend on stdio.h.If you follow these rules then the order that you
#include
headers does not matter (unless you use precompiled headers: then the precompiled header comes first in each cpp file, but does not need to be included from header files).查看类似的问题学习创作标题的好方法。
简而言之,您希望在定义防护内定义每个标头,以防止在编译期间多次包含标头。完成这些后,对于每个 .h 和 .cpp 文件,只需包含解析任何声明所需的标头即可。预处理器和编译器将处理剩下的事情。
Take a look at a similar question to learn a good approach to authoring headers.
In short, you want to define each header inside a definition guard that prevents headers from being included more then once during compilation. With those in place, for each .h and .cpp file, just include the headers needed to resolve any declarations. The pre-processor and compiler will take care of the rest.
C继承类B。因此,它应该看到标识符
B
。因此,在此处包含Bh
-D 具有类
A
、B
的对象。因此,在“Dh”本身中包含A, B 标头。
D.cpp
请注意,每个标头都需要包含在其相应的源文件中。独立地考虑每个源文件,看看所使用的内容是否是先前在源文件中定义的。
C inherits class B. So, it should see the identifier
B
. So, includeB.h
here -D has objects of class
A
,B
. So, include headers ofA, B
in the "D.h" itself.D.cpp
Note that every header needs to be included in it's corresponding source file. Think of each source file independently and see whether what ever is used is earlier defined or not in the source file.
Ah 应包含 SFML
A.cpp 应包含 Ah
Dh 应包含 SFML、Ah 和 Ch
D.cpp 应包含 Dh
main.cpp 应包含它直接使用的 A、B、C、D 和 SFML 中的任何一个。
通常,在 .cpp 文件中,我不包含任何您知道必须包含在其相应 .h 中的标头,因为它们包含该 .h 中定义的类的数据成员的定义。因此,在我的代码中 D.cpp 不会包含 Ah That's just me,不过,您可能更愿意包含它,只是为了提醒您 .cpp 文件(大概)使用它。
这留下了 stdafx - 你需要它的地方取决于它里面的东西的用途。可能到处都需要它,并且 MSVC 不会处理(或处理但丢弃?)源文件中
#include "stdafx.h"
之前的任何内容,因此它应该是每个 .cpp 中的第一件事文件并出现在其他地方。所有头文件都应该具有多重包含保护。
您可以将 SFML(或您喜欢的任何其他内容)添加到 stdafx.h,在这种情况下,您也可以从其他地方删除这些包含内容。
完成此操作后,在每个文件中包含标头的顺序不再重要。所以你可以做你喜欢做的事,但我推荐 Google 的 C++ 风格指南主题(单击箭头事物),调整以适应 stdafx.h。
A.h should include SFML
A.cpp should include A.h
D.h should include SFML, A.h and C.h
D.cpp should include D.h
main.cpp should include whichever of A, B, C, D and SFML that it uses directly.
Generally in a .cpp file I don't include any headers that you know must be included by its corresponding .h because they contain the definitions of data members of classes defined in that .h. Hence, in my code D.cpp would not include A.h. That's just me, though, you might prefer to include it anyway just to remind you that the .cpp file (presumably) uses it.
This leaves stdafx - where you need this depends what uses the things in it. Probably it's needed everywhere, and MSVC doesn't process (or processes but discards?) anything before
#include "stdafx.h"
in a source file, so it should be the first thing in each .cpp file and appear nowhere else.All header files should have multiple-include guards.
You could add SFML (or anything else you feel like) to stdafx.h, in which case you might as well remove those includes from everywhere else.
Once you've done this, it no longer matters what order you include the headers in each file. So you can do what you like, but I recommend Google's C++ style guide on the subject (click on the arrow thing), adjusted to account for stdafx.h.
取决于依赖关系。与 C# 和其他类似语言不同,C++ 按照编写的顺序执行操作,因此可能存在问题。如果您的顺序确实有问题,那么它将无法编译。
Depends on dependencies. Unlike C# and other similar languages, C++ does things in the order it is written, so there may be an issue. If you do have a problem with the order then it will not compile.