38

LearnCpp.com | 1.10 — 初步了解预处理器。在Header guards下,有这些代码片段:

添加.h:

#include "mymath.h"
int add(int x, int y);

减去.h:

#include "mymath.h"
int subtract(int x, int y);

主.cpp:

#include "add.h"
#include "subtract.h"

在实现header guard时,提到如下:

#ifndef ADD_H
#define ADD_H

// your declarations here

#endif
  • 什么可以在这里声明?而且,应该int main()#endif吗?
  • 添加_H约定还是必须做的事情?

谢谢。

4

5 回答 5

68

FILENAME_H是一个约定。如果你真的想要,你可以将它#ifndef FLUFFY_KITTENS用作标题保护(前提是它没有在其他任何地方定义),但如果你在其他地方定义它,那将是一个棘手的错误,比如作为某物或其他东西的小猫数量。

在头文件 add.h 中,声明实际上介于#ifndef和之间#endif

#ifndef ADD_H
#define ADD_H

#include "mymath.h"
int add(int x, int y);

#endif

最后,int main()不应该在头文件中。它应该始终在一个.cpp文件中。

要清除它:

#ifndef ADD_H基本上意味着“如果 ADD_H 没有#defined在文件中或包含文件中,则编译#ifndef#endif指令之间的代码”。#include "add.h"因此,如果您在一个文件中多次尝试.cpp,编译器将看到 ADD_H 已经是什么#defined,并将忽略 和 之间的#ifndef代码#endif。标头保护仅防止头文件多次包含在同一.cpp文件中。标头保护不会阻止其他.cpp文件包含头文件。但所有.cpp文件只能包含一次受保护的头文件。

于 2011-01-22T09:26:11.023 回答
19
  • 预处理一个实现(“.cpp”)文件的结果是一个翻译单元(TU)。

  • 标头可以包含其他标头,因此一个标头可以在同一个 TU 中间接包含多次。(你的 mymath.h 就是一个例子。)

  • 每个 TU 最多只能出现一次定义。(某些定义也不能在多个 TU 中;这种情况略有不同,此处不讨论。)

  • 包含保护解决的问题是在一个 TU 中多次包含给定标头时防止多个定义错误。

  • 包含守卫通过“包装”标头的内容来工作,使得第二个和后续包含是无操作的。#ifndef/#define 指令应该是文件的前两行,#endif 应该是最后一行。

  • 包含守卫仅用于标头中。不要在头文件中定义你的 main 函数:把它放在一个实现文件中。

如果您有一个将定义类型并声明函数的标头,但也需要标头本身:

#include "other_header.h"

struct Example {};

void f();

用包含守卫“包装”它会给出文件的完整内容:

#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE

#include "other_header.h"

struct Example {};

void f();

#endif

用于包含保护的名称必须是唯一的,否则冲突的名称会产生令人困惑的结果。这些名称只是简单的宏,语言中没有任何东西强制执行某种样式。但是,项目约定通常会提出要求。您可以在 SO 和其他地方找到几种不同的包含守卫命名样式;这个答案给出了很好的标准和很好的概述。

于 2011-01-22T10:25:07.353 回答
3

所有标头守卫所做的就是只允许您的标头包含一次。(如果它们被多次包含,它们将被忽略。)

您使用的名称无关紧要,但通常使用大写的文件名,包括您演示的扩展名。

main真的应该在一个.cpp文件中,但是如果你把它放在一个标题中,把它放在守卫里面,这样它就不会被多次声明。

于 2011-01-22T09:21:08.687 回答
1

不, int main() 在 .cpp 中。声明是您要放在标题中的其他内容。_H是一个约定,您可以在周围看到各种标头保护约定。

于 2011-01-22T09:20:30.133 回答
1

我在头文件和定义中声明了一个声明,或者int main()source.cpp文件中声明。

_H是否仅表明有人将使用包含防护来包含头文件。

如果您使用的是 MSVC++,您也可以使用#pragma once

于 2011-01-22T09:38:43.523 回答