在头文件中包含头文件与在实现文件中包含头文件有什么区别?
这个
例如:
// test.h
#include"globals.h"
class Test
{
Test();
};
对
//test.cpp
#include"globals.h"
Test::Test()
{
}
一般原则是您希望尽可能减少依赖关系,因此:
如果您的接口(.h)引用给定标头中的任何内容,则该标头需要#included在接口(.h)中
如果您仅在您的实现(.cpp)(而不是在您的界面中)引用给定的标头,那么您应该只在实现中#include该标头
您还应该尝试仅 #include 实际需要的标头,尽管这在大型项目的生命周期中可能很难维护
因此,对于上面的示例,如果您没有在 test.h 中引用 globals.h 中的任何内容,但在 test.cpp 中引用了它,则 #include 应该放在 test.cpp 中。如果您在 test.h 中引用了 globals.h 中的任何内容,那么您需要 test.h 中的#include。
如果要包含一些特定于实现的外部标头,最好将它们包含在 cpp 文件中,以减少标头对 API 文件的依赖。在 cpp 文件中包含第三方标头是隐藏数据的好方法,这样库用户就不会太了解您的引用。
在需要的地方包含头文件是一种很好的做法,可以提高代码的合格性并使您的项目可以轻松修改以供将来的开发使用。
唯一编译的就是
.cpp
文件。
实际上,这不是真的,编译了从
.cpp
生成的文件。
生成此其他文件时,
#include
指令有效地将包含文件的内容复制并粘贴到生成的文件中。
这就是所发生的一切。
#include
是一个简单的文本替换。该行被上述文件的内容替换。所以,如果你在 B.h 中包含 A.h,在 C.cpp 中包含 B.h,那么 A.h 的内容最终将被粘贴到 C.cpp 中。
我们通常会尽量避免此类标头中的标头。通常可以使用前向声明来代替。例如。
class Global;
。最大的例外是基类。定义派生类的标头必须包含基类的标头。
如果您以标头和库的形式提供 API 代码,那么您必须确保定义接口的头文件中不包含内部私有头文件。在这种情况下,您将所有私有文件包含在 CPP 文件中,该文件将被编译并位于 .lib 或 .a 或 .dylib 文件中。否则,这对于使用您的 API 的用户来说将会是一个问题。
您应该确保您包含在标头中的文件表明可以在包含 test.h 的位置访问 globals.h。如果不是这种情况,则将 globals.h 包含在 CPP 文件中。
据我所知,在源文件或头文件中包含头文件没有任何区别。请注意,#include 是一个预处理器宏,它所做的只是替换包含头文件的位置处的内容。
在上面的示例中,如果 globals.h 看起来像这样,
#ifndef GLOBALS_H_
#define GLOBALS_H_
#define MYGLOBAL_VARIABLE 10
#endif /* GLOBALS_H_ */
预处理器完成其工作后的源文件将如下所示。
/* #include "globals.h" */
#ifndef GLOBALS_H_
#define GLOBALS_H_
#define MYGLOBAL_VARIABLE 10
#endif /* GLOBALS_H_ */
Test::Test()
{
}
没有什么区别。
.h
文件用于定义类和变量,而 .cpp
文件是实现。
我们使用:
#include <>
当 lib/h 文件在 lib 文件夹中可用时。#include ""
当它存在于当前文件夹中时..(未给出lib路径)