如何包含头文件

时间:2010-09-18 09:11:26

标签: c++ header-files

导入头文件的方式有关系吗?我看过双引号和箭头。

#include <stdlib.h>
#include "Some_Header.h"

如果他们也以某种方式资本化是否重要?试验这一点似乎无关紧要,但我认为教程必须有理由这样做。

另一个问题是,(来自Java),我如何访问其定义的文件之外的类?说,我有one.cpp和two.cpp。

在one.cpp中:

class Something {
    ...

在two.cpp中:

class SomethingElse {
    Something *example;
    ...

那样的?在Java中,您只需在“public”前面添加一个类名。在C ++中,争吵类似乎有点困难。

5 个答案:

答案 0 :(得分:27)

#include指令中的尖括号表示搜索路径仅限于“system”包含目录。双引号表示搜索路径包含当前目录,后跟系统包含目录。

当您的操作系统使用区分大小写的文件系统时,文件名的大小写非常重要。听起来您可能正在使用Windows或Mac OS X,默认情况下文件名不区分大小写。

答案 1 :(得分:7)

尖括号在系统标题目录中查找标题(例如/usr/include)。引号只是绝对路径名或相对路径名,例如/path/to/header.h../headers/abc.h

要从其他文件访问类,只需#include该类的其他文件。请务必构建程序,以便不会多次包含任何文件。

答案 2 :(得分:7)

问题1

  

我如何导入标题是否重要   文件?   它们是否被资本化是否重要?   某种方式呢?

没关系,但通常的做法是,

  • 对系统使用尖括号 头。
  • 用户的双引号 定义的标题(您自己的标题)

问题2&amp; 3

  

另一个问题是,(来自Java   在这里),我如何访问外面的课程   它定义的文件是什么?

您需要将类定义放在头文件中,并将该头文件包含在您想要使用该类的任何位置。 对于您的情况,它将如下所示。

//One.h
#ifndef ONE_H
#define ONE_H
class Something
{
public:
    void doSomething(){}

};
#endif

//Two.cpp
#include "One.h"
class SomethingElse
{
   SomeThing *example;
};

答案 3 :(得分:7)

首先是一个简单的问题:

  

它们是否也以某种方式资本化是否重要?

在大多数情况下,includes引用文件,编译器应该能够找到您在系统中包含的文件。因此,在文件系统区分大小写的所有系统中,大写很重要。如果要保持最低的可移植性,则应在文件名和include中保持一致。 (默认情况下,所有linux 和mac os 都有区分大小写的文件系统,在windows中你可以配置NTFS也区分大小写)

现在,文件的命名方式实际上是否重要?不,它没有,只要你在夹杂物中保持一致。另请注意,建议遵循模式以简化包含。

  

导入头文件的方式是否重要?

标准目前尚不清楚,不同的实现遵循不同的路径。标准定义它们可能不同,因为编译器将搜索包含文件的位置和顺序是实现定义的,如果包含使用尖括号或双引号,则可能不同。如果包含引号无法找到该文件,则编译器必须回退以处理include,就好像它是用尖括号编写的那样。

#include <x.h> // search in order in set1 of directories
#include "x.h" // search in order in set2 of directories
               // if search fails, search also in set1

这意味着如果文件仅出现在set1中,则两种类型的包含都将找到它。如果set2中存在文件而不是set1,则只有引用包含它才能找到它。如果set1和set2中存在具有相同名称的不同文件,则每个包含类型将查找并包含不同的文件。如果set1和set2的公共子集中存在两个具有相同名称的文件,但这些集的顺序不同,则每个包含类型都可以找到不同的文件。

回到现实世界,大多数编译器将仅包含set2中的当前目录,其中set1是所有系统包含位置(通常可以使用编译器参数进行扩展)在这些情况下,如果文件仅存在于当前目录,#include "a.h"会找到它,但#include <a.h>不会。

现在,无论这是否是常见行为,都有一些隐含的语义在C / C ++中是惯用的。通常,方括号用于包含系统标头和外部标头,而双引号用于包含本地文件。关于同一项目中的库是否应被视为本地外部,存在一个灰色区域。也就是说,即使总是包含双引号也行,大多数人都会使用角度引用来引用不属于当前模块的标题。

最后,虽然我所知道的编译器没有这样做,但是标准允许实现(编译器)不将标准头文件生成为真实文件,而是在内部处理标准头文件的包含。这是理论上#include "vector"可能无法包含std::vector类(或任何其他标准头)的定义的唯一情况。但这不是一个实际问题,我不认为它会永远存在。

答案 4 :(得分:0)

首先,#include是C预处理器指令,并不严格地说是C ++语言的一部分。您可以找到更多相关信息here,尽管这是专门针对GNU C预处理器的,因此可能与您使用的不同。我认为你应该总是在包含文件中假设区分大小写。不这样做可能会使您难以将代码移植到区分大小写的操作系统,例如UNIX。

使用“”或&lt;&gt;如上所述是相当微妙的,大多数时候你会注意到没有区别。使用“”通常首先搜索当前目录。我倾向于不使用它:

  • 我知道我的标题在哪里 - 我总是在编译行上用-I指定它们。
  • 我之前被抓到了一个本地方面的标题副本覆盖了我希望拿起的中央副本。

我还注意到一些副作用,例如当使用make来创建依赖树时(我不能完全回想起这个问题 - 它确实对待不同的包括不同的,包括一些而不是其他,但这是大约7年前)

其次,关于如何在其他文件中引用函数的问题将被回答here /