如果一个库包含在类头中,然后这个头包含在另一个类中,我是否必须再次包含该库?
例如:
#ifndef A_H
#define A_H
#include<someLibrary.h>
class A{
...
}
#endif
然后另一个类包括A.h标题
#include<A.h> //include class A
class B{
...
}
我是否必须在B类中加入“someLibrary.h”?
答案 0 :(得分:5)
不,#include
是可传递的。
但是,如果您的第二个文件本身使用来自 someLibrary 的符号,则重新包含标题的好方法。这样你就不会希望和祈祷&#34;你永远不会删除中间包括。如果每个源文件#include
都是它直接需要的东西,那么您的代码库将更加健壮。标题保护可以防止这是一个浪费的政策。
答案 1 :(得分:4)
您不包含类或库,只包含标题,这是文本操作(有点像预处理器完成的复制和粘贴)。
详细了解C/C++ preprocessor和GNU cpp。
您可以要求编译器向您显示源文件foo.cc
的预处理形式,例如:使用g++ -Wall -C -E foo.cc
(它将溢出 stdout 预处理表单)
对于一个小项目(例如小于200KLOC),所有翻译单元只包含一个通用头文件是明智的(我相信有很多小头文件是坏习惯,所以我通常不止一个每个头文件的类定义)。顺便说一句,(单头文件)方法对于precompiled headers是友好的。有些人喜欢在单个标题中拥有几个自己的#include
- d个子标题。
请注意,大多数C ++标准头文件(如<map>
或<vector>
....)会带来大量文本,因此您不希望使用微小的编译单元(在我的Linux系统上, #include <vector>
拖动了超过一万行,因此只有几十个你的源代码行对编译器来说是低效的)
另请注意,C ++类定义通常具有许多内联成员函数(并且您实际上希望在同一个头文件中提供该内联函数的主体)。所以C ++标题代码往往很大......
(有些人喜欢在许多子标题中打破单个头文件,这些头文件总是包含在一起)
答案 2 :(得分:4)
preprocessor #include
指令完全符合名称的含义,实际上包含指令所在地的文件。
简单示例:假设我们必须使用文件,首先是名为a.h
// Our class
class A
{
// Stuff for the class
};
// End of the class
然后是源文件a.cpp
:
// Include header file
#include "a.h"
// Header file included
int main()
{
// Code
}
预处理器生成单个文件,如
// Include header file
// Our class
class A
{
// Stuff for the class
};
// End of the class
// Header file included
int main()
{
// Code
}
这种包含是递归的,因此如果头文件包含另一个头文件,那么也将包含其他头文件。
预处理器生成的源文件称为translation unit,是编译器实际看到的。
以上是对现代预处理器如何工作的简化,虽然它可以单独运行以创建预处理的源文件,但预处理器是简化解析过程的编译器的一部分更为常见。
您还应注意您使用的术语不正确。库可以(通常也有)具有一个或多个头文件,这些头文件在编译源代码时使用。然后,库通常(但不总是)包含一个特殊的库文件,该文件与编译器创建的目标文件链接。
没有链接库的库称为仅头库。