如何正确使用#include指令?

有没有关于如何正确使用#include ? 我没有找到任何可以详细解释这种用法的C / C ++教科书。 在正式项目中,我总是对处理它感到困惑。

  • 如果你有钱,请检查John Lakos的大规模C ++软件设计。
  • 谷歌C ++编码指南也有一些好的东西。
  • 在线检查Sutter Herb材料(博客)。

基本上你需要了解哪些包含头不是必需的,例如。 前瞻性声明 还要尝试确保包含文件逐个编译,并且只在必须时将#includes放在h文件中(例如模板)。

总是让我失望的最重要的是:

这将在标题路径中搜索:

 #include  

这将在您的本地目录中搜索:

 #include "myfile.h" 

你应该对每个标题做的第二件事是:

myfilename.h:

 #ifndef MYFILENAME_H #define MYFILENAME_H //put code here #endif 

这种模式意味着你不能在重新定义你的编译中的标题时干掉(干杯到orsogufo指出我这被称为“包含守卫”)。 做一些关于C编译器如何实际编译文件(链接之前)的阅读,因为这将使#define和#include的世界对你有很大的意义,C语言编译器在解析文本方面不是很智能。 (然而,C编译器本身是另一回事)

因此,您的编译器可能支持包含文件的2个唯一搜索路径:
非正式地,我们可以调用系统包含路径和用户包含路径。
#include 搜索系统包含路径。
#include“XX”搜索用户包含路径,然后系统包含路径。

检查标准草案n2521:
第16.2节:

 2 A preprocessing directive of the form # include < h-char-sequence> new-line searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined. 3 A preprocessing directive of the form # include " q-char-sequence" new-line causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read # include < h-char-sequence> new-line with the identical contained sequence (including > characters, if any) from the original directive. 

一个例子就是gcc

  -isystem  Add  to the start of the system include path -idirafter  Add  to the end of the system include path -iwithprefix  Add  to the end of the system include path -iquote  Add  to the end of the quote include path -iwithprefixbefore  Add  to the end of the main include path -I  Add  to the end of the main include path 

要查看您的gcc搜索的位置,请执行以下操作:

 g++ -v -E -xc++ /dev/null -I LOOK_IN_HERE #include "..." search starts here: #include <...> search starts here: LOOK_IN_HERE /usr/include/c++/4.0.0 /usr/include/c++/4.0.0/i686-apple-darwin9 /usr/include/c++/4.0.0/backward /usr/local/include /usr/lib/gcc/i686-apple-darwin9/4.0.1/include /usr/include /System/Library/Frameworks (framework directory) /Library/Frameworks (framework directory) End of search list. 

那么你如何使用这些知识呢?
有几种思想流派。 但我总是列出我的库,从最具体到最一般。

文件:plop.cpp

 #include "plop.h" #include "plop-used-class.h" /// C Header Files #include  // I know bad example but I drew a blank /// C++ Header files #include  #include  

这样,如果头文件“plop-used-class.h”应该包含,那么编译器就可以了。 如果我将放在顶部,则此错误将从编译器中隐藏。

除了其他注释之外,请记住,如果只有指针或引用,则不需要#include另一个头中的头。 例如:

标题要求:

 #include "Yh" class X { Y y; // need header for Y }; 

标头不需要:

 class Y; class X { Y* y; // don't need header for Y }; //#include "Yh" in .cpp file 

第二个示例编译速度更快,依赖性更低。 这在大型代码库中很重要。

头文件是C分离接口和实现的方式。 它们分为两种类型:标准和用户定义的头文件。 标准头文件(如string.h)允许我们访问底层C库的function。 您应该在每个使用相关function的.c文件中#include它。 通常这会在#include中使用括号。用户定义的头文件会将函数的实现暴露给其他程序员或C代码的其他部分。 如果你已经实现了一个名为rational.c的模块用于有理数的计算,那么它的公共接口应该有一个相应的rational.h文件。 每个使用该function的文件都应该#include rational.h,而且rational.c应该#include它。 通常这是使用#include“rational.h”完成的。编译#includes的部分称为C预处理器 。 它主要是文本替换和粘贴文本。 Spence在他的模式中是正确的,以防止重复#includes,这会搞乱命名空间。 这是包含的基础, GNU Make为您提供了更多的function,也带来了更多的麻烦。

只是Andy Brice答案的附录,您还可以使用函数返回值的前向声明:

 class Question; class Answer; class UniversityChallenge { ... Answer AskQuestion( Question* ); ... }; 

这里有一个问题的链接,我回答了一些好的答案http://bytes.com/groups/c/606466-forward-declaration-allowed 。

查看有关使用#include#include 的讨论 ,了解C ++包含的C库。

编辑:安迪布莱斯也以更简洁的方式提出这一点。

在null的答案中跟进,最重要的是要考虑你的#include’s。

当您编写#include时,预处理器字面上包含您在当前文件中列出的文件的内容,包括那些文件中的任何#include。 这显然会在编译时导致非常大的文件(coad膨胀),所以你需要仔细考虑是否需要#include。

在标准代码文件布局中,对于具有类和函数声明的类,然后是.cpp实现文件,您有.h文件,您应该注意头文件中的#includes数。 这是因为,每次对头文件进行更改时,任何包含它的文件(即使用您的类的文件)也必须重新编译; 如果标头本身有很多包含,那么使用该类的每个文件在编译时都会显着膨胀。

最好在可能的情况下使用前向声明,以便您可以编写方法签名等,然后#include .cpp文件中的相关文件,以便您可以实际使用代码所依赖的类和结构。

 //In myclass.h class UtilClass; //Forward declaration of UtilClass - avoids having to #include untilclass.h here class MyClass { MyClass(); ~MyClass(); void DoSomethingWithUtils(UtilClass *util); //This will compile due to forward declaration above }; //Then in the .cpp #include utilclass.h void MyClass::DoSomethingWithUtils(UtilClass *util) { util->DoSomething(); //This will compile, because the class definition is included locally in this .cpp file. } 

如果yourfile.h位于当前工作目录中,则使用#include "yourfile.h"如果yourfile.h文件的路径包含在C ++ include目录中(在配置中的某个位置,示例: c:\mylib\yourfile.h ,则使用#include c:\mylib\yourfile.h ,路径c:\mylib\必须指定为包含目录)另外,您可以包含.cpp和.hpp(h plus plus)。 有一组特定的文件可以写成: #include 。 对于特定的示例工作,您需要using namespace std;指定using namespace std;

有一个非常好的软件与microsoft的visual c ++集成,并显示包含路径。 http://www.profactor.co.uk/includemanager.php