繁体   English   中英

如何包括头文件

[英]How to include 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 ++中,争吵类似乎更加困难。

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

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

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

要从其他文件访问类,只需在该类中#include另一个文件。 确保对程序进行结构设计,以便不包含任何文件。

问题1

我导入头文件有关系吗? 是否也以某种方式大写它们是否重要?

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

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

问题2和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;
};

首先是一个简单的问题:

是否也以某种方式大写它们是否重要?

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

现在,文件的命名实际上有关系吗? 不,不是这样,只要您对内含物保持一致即可。 另请注意,建议遵循一种模式以简化包含。

我导入头文件有关系吗?

到目前为止,该标准还不是很明确,并且不同的实现遵循不同的路径。 该标准定义它们可以不同,因为编译器将搜索包含文件的位置和顺序集是实现定义的,并且如果包含在尖括号或双引号中,则可以不同。 如果包含引号的内容无法找到文件,则编译器必须后退以处理包含文件,就好像它是用尖括号编写的一样。

#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中不存在,则只有引号include可以找到它。 如果set1和set2中存在具有相同名称的不同文件,则每种包含类型将查找并包含一个不同的文件。 如果set1和set2的公共子集中存在两个具有相同名称的文件,但是这些集合的顺序不同,则每种包含类型都可以找到一个不同的文件。

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

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

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

首先, #include是C预处理程序指令,并非严格地属于C ++语言。 尽管这是专门针对GNU C预处理程序的,但您可以在此处找到更多信息,因此可能与您所使用的有所不同。 我认为您应该始终在包含文件中假设大小写敏感。 否则,可能很难将代码移植到区分大小写的OS(例如UNIX)上。

如上所述,“”或<>的使用非常微妙,大多数时候您不会注意到它们的区别。 通常使用“”首先搜索当前目录。 我倾向于不将其用作:

  • 我知道我的标头在哪里-我总是在编译行上用-I指定它们。
  • 之前,当我在本地合并的标头副本覆盖我希望提取的中央副本时,我就被困住了。

我还注意到了一些副作用,例如使用make创建依赖关系树时(我不太记得这个问题-它确实以不同的方式对待不同的包含,遵循了一些而不是其他,但这大约是7年前)

其次,关于如何在其他文件中引用函数的问题在此处得到解答/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM