LearnCpp.com | 1.10 — A first look at the preprocessor。在标题保护下,有以下代码段:
add.h:
#include "mymath.h"
int add(int x, int y);
subtract.h:
#include "mymath.h"
int subtract(int x, int y);
main.cpp中:
#include "add.h"
#include "subtract.h"
在实施标题保护时,提到如下:
#ifndef ADD_H
#define ADD_H
// your declarations here
#endif
int main()
应该#endif
之后?_H
约定还是必须做的事情?感谢。
答案 0 :(得分:51)
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
和{{之间的代码1}}。标头保护仅阻止在同一#endif
文件中多次包含头文件。标头保护不会阻止其他.cpp
文件包含头文件。但是,所有.cpp
个文件都可以包含受保护的头文件仅一次。
答案 1 :(得分:17)
预处理一个实现(“。cpp”)文件的结果是翻译单元(TU)。
标题可以包含其他标题,因此标题可以在同一个TU中间接包含多次。 (你的mymath.h就是一个例子。)
每个TU最多只能发生一次定义。 (某些定义也必须不在多个TU中;这种情况略有不同,此处不再讨论。)
问题包括警卫解决在一个TU内多次包含一个给定标题时阻止多个定义错误。
通过“包装”标题的内容来包含警卫工作,使第二个和后续包含为no-ops。 #ifndef / #define指令应该是文件的前两行,而#endif应该是最后一行。
包含防护仅用于标题。不要在标题中定义主函数:将其放在实现文件中。
如果你有一个标题来定义一个类型并声明一个函数,但它本身也需要一个标题:
#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和其他地方你可以找到几种不同的防护命名样式; this answer提供了良好的标准和良好的概述。
答案 2 :(得分:3)
所有标题保护程序都只允许您的标题包含一次。 (如果它们被多次包括在内,则会被忽略。)
您使用的名称并不重要,但通常使用大写字母中的文件名,包括您演示的扩展程序。
你的main
应该放在.cpp
文件中,但是如果你把它放在标题中,请将它放在警卫中,这样就不会多次声明。
答案 3 :(得分:1)
不,int main()进入.cpp。声明是你要放在标题中的其他东西。 _H
是一种约定,你可以看到各种标题保护惯例。
答案 4 :(得分:1)
我在头文件和定义中声明了一个声明,或int main()
在source.cpp
文件中声明。
_H
只是表明某人将使用包含警卫来包含头文件。
如果您使用的是MSVC ++,还可以使用#pragma once