C++中头文件的保护块是什么?

5

我正在尝试使用Code::Blocks IDE创建一个C++类,其中有一个名为“Guard block”的字段。我已经搜索过但没有找到任何有用的信息。这个字段是用来做什么的?谢谢。


4
可能是需要使用头文件保护(Include guards)吗? - Seth Carnegie
2个回答

11

保护块被用来防止同一编译单元(C++文件)多次包含头文件。它们看起来像这样:

// Foo.h
#ifndef INCLUDE_FILE_NAME_HERE_H_
#define INCLUDE_FILE_NAME_HERE_H_

class Foo
{
};


#endif

如果你在多个文件中包含相同的文件,你将会遇到多重定义错误。在小型项目中不需要使用include guards,但在任何中大型项目中都变得至关重要。我经常在我编写的头文件中使用它。


感谢您的快速回复。还有一件事是,我看到我创建的类的头文件被包含在类的.cpp文件中,这对我来说并没有太多意义。我不确定为什么Code::Blocks会这样做 =/ - chrislgarry
@快速排序的头文件包含在.cpp文件中,因为类型和常量在头文件中定义,而类在那里声明。 - David Heffernan
谢谢David。天哪,你回复得真快。所以我的类的头文件(“Deck.cpp”)只是向编译器提供了一个可能出现在main.cpp中的所有声明列表,而没有包含任何实现细节,因此不会出现编译错误,如果该项确实在主文件中实例化,则编译器会查找与头文件相关联的Deck.cpp文件,并将实现细节插入到main.cpp中? - chrislgarry
1
@Quicksort 嗯,不完全是那样的,但在评论中很难深入讨论细节。主要头文件的作用在于允许您在其他翻译单元中调用函数,而无需多次编写声明。关键在于理解声明和定义之间的区别。 - David Heffernan
好的,我会再做一些搜索。感谢您的帮助! - chrislgarry

1

守卫块用于防止在单个翻译单元中多次包含头文件。当您包含许多头文件时,这通常是一个问题,而这些头文件反过来又包含常见的标准头文件。

同一文件的多重包含的问题在于它导致相同的符号被多次定义。

守卫子句可以使用#define#ifdef语句处理,但使用非标准的、普遍存在的#pragma once则更简单。

// foo.h
#pragma once

int foo(void);
// etc.

谢谢您的快速回复。在工业界中,使用“#pragma once”是常见的吗? - chrislgarry
1
这要看情况。如果你很在意可移植性,那么你不会使用它,因为它不是可移植的,也就是说不被标准支持。但所有流行的编译器都实现了它,所以在实践中这不是一个问题。如果你有一天遇到一个不支持它的编译器,那么切换到旧式的保护方式也很容易。 - David Heffernan
1
#IFNDEF MYTHING \n #DEFINE MYTHING \n #pragma once 在所有可能快速的编译器上都很快(请确保 ifdef 放在第一位)。 - Mooing Duck
@MooingDuck 为什么在使用 #pragma once 的情况下还要有 #ifndef……#endif?这是为了增加可移植性吗? - David Heffernan
如果使用#pragma once,不支持该指令的编译器会报错吗? - Seth Carnegie
@DavidHeffernan,SethCarnegie:一些编译器会检测到头文件以#IFNDEF开头,并且如果以此开头,则第二次不会再次“触及”该文件。理解#pragma once的编译器也会这样做,但是pragma不必是文件中的第一件事。根据C标准,不理解#pragma的编译器需要忽略它。愚蠢的编译器将打开文件,并被#IFNDEF(第二次)阻止。 - Mooing Duck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接