我是编程新手,头文件的话题在我开始大量使用头文件后让我陷入了困境。除此之外,我试图使用预编译头。我也使用SFML库,所以我有那些头也必须包括在内。
现在我有stdafx.h, main.cpp,然后类A, B, C和D包含在A.h, A.cpp, B.h, B.cpp, C.h, C.cpp, D.h和d.p。
如果
- 所有类包含一个SFML类的实例
- D类包含A类和C类的实例
- 类C包含类B的实例我的代码:(注意:所有的头都有头警卫)
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"
刘昀
#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"
我的理念是,在编写良好的代码中,头文件应该包括它们所依赖的所有其他头文件。我的理由是,不应该包含头文件并因此得到编译器错误。因此,每个头文件(在#ifdef
或#pragma once
include guard之后)应该包含它所依赖的所有其他头文件。
为了非正式地测试您是否记得在头文件中包含正确的头文件,*.cpp文件应该#包含应该工作的最小头文件集。因此,如果A
, B
, C
和D
有单独的头文件,并且您的cpp文件使用D
类,那么它应该只包含D.h。不会导致编译错误,因为D.h #include
s A.h和C.h, C.h包含B.h,并且A.h和B.h包含SFML头文件(不管它是什么)。如果合适的话,C.h和D.h可以包含SFML头文件,但如果您可以确定依赖项(B.h和A.h)已经包含它,则不是必需的。
"StdAfx.h"
作为第一个头文件,这导致许多开发人员简单地将整个项目的所有#include
放在StdAfx.h中,而不在任何其他头文件中使用#include
。我不建议这么做。或者,他们将把所有外部依赖放在StdAfx.h中(例如windows.h, boost headers),并在其他地方#include本地依赖,以便更改单个头文件不一定会导致整个项目重新构建。
我写代码的方式,我的大多数CPP文件包括StdAfx.h,以及相应的。h文件。所以a.p p包括stdafx。h和A.h, b.p p包括stdafx。h和B.h,以此类推。唯一放置在cpp文件中的其他#include
s是头文件不公开的"内部"依赖项。例如,如果类A
调用printf()
,则 a.p (而不是A.h)将#include <stdio.h>
,因为A.h不依赖于stdio.h。
如果你遵循这些规则,那么你的#include
头文件的顺序并不重要(除非你使用预编译的头文件:那么预编译的头文件在每个cpp文件中首先出现,但不需要包含在头文件中)。
看一个类似的问题,学习一个编写头文件的好方法。
简而言之,您希望在定义保护中定义每个头文件,以防止在编译过程中多次包含头文件。有了这些,对于每个.h和.cpp文件,只需包含解析任何声明所需的头文件。预处理器和编译器将负责其余的工作。
C 继承类 B 。因此,它应该看到标识符B
。因此,在这里包含B.h
-
#include "B.h" // Newly added
// Or you can forward declare class B ;
class C: public B
{
};
D有A
, B
类的对象。因此,在"D.h"本身中包含A, B
的头文件。
class D
{
A a; // Should see the definition of class A
C c; // Should see the definition of class B
//sfml class
}
D.cpp
#include "A.h"
#include "C.h"
#include "D.h" // Notice that A.h and C.h should definitely placed before
注意,每个头文件都需要包含在相应的源文件中。独立考虑每个源文件,并查看所使用的内容是否在源文件中早前定义过。
A.h应包含SFML
a.p p应该包含A.h
D.h应包括SFML、A.h和C.h
d.p p应该包含D.h
main.cpp应该包括它直接使用的A、B、C、D和SFML中的任意一个。
一般来说,在一个。cpp文件中,我不包含任何你知道必须包含在对应的。h中的头文件,因为它们包含了在。h中定义的类的数据成员的定义。因此,在我的代码中d.p p不包含A.h。这只是我的想法,不过,您可能更愿意包含它,只是为了提醒您.cpp文件(大概)使用它。
这就留下了stdafx——你需要在哪里——这取决于里面的东西是什么用的。可能到处都需要它,并且MSVC不处理(或处理但丢弃?)源文件中#include "stdafx.h"
之前的任何内容,因此它应该是每个.cpp文件中的第一个内容,并且在其他任何地方都不会出现。
所有头文件都应该有多重包含保护符。
您可以在stdafx.h中添加SFML(或任何您喜欢的内容),在这种情况下,您不妨从其他任何地方删除这些包含。
一旦这样做了,在每个文件中包含头文件的顺序就不再重要了。所以你可以做你喜欢的,但我推荐谷歌的c++风格指南(点击箭头的东西),调整为考虑stdafx.h。取决于依赖项。与c#和其他类似的语言不同,c++按照编写的顺序执行操作,因此可能存在问题。如果您的订单有问题,那么它将无法编译