#include "DLLDefines.h"
#include "DLLDefines.h"
Run Code Online (Sandbox Code Playgroud)
以上实际上是通过编译,但为什么呢?
jal*_*alf 14
嗯,这是合法的,因为它必须是合法的.因为您经常多次包含相同的标题,甚至没有意识到它.
您可以在.cpp文件中包含两个标头,每个标头包含许多文件,其中一些文件可能包含在内.
例如,所有标准库标题(例如,string或者说vector)都可能包含在大多数标题中.因此,您很快就会在同一个.cpp文件中多次间接包含相同的标头.
简而言之,它必须工作,否则所有C++代码都会崩溃.
至于它是如何工作的,通常是通过包括警卫.请记住,#include只需执行简单的复制/粘贴:它会在#include站点中插入头文件的内容.
因此,假设您有一个header.h包含以下内容的头文件:
class MyClass {};
Run Code Online (Sandbox Code Playgroud)
现在让我们创建一个cpp文件,其中包含两次:
#include "header.h"
#include "header.h"
Run Code Online (Sandbox Code Playgroud)
预处理器将其扩展为:
class MyClass {};
class MyClass {};
Run Code Online (Sandbox Code Playgroud)
这显然会导致错误:同一个类被定义两次.所以这不起作用.相反,让我们修改标题以包含包含警戒:
#ifndef HEADER_H
#define HEADER_H
class MyClass {};
#endif
Run Code Online (Sandbox Code Playgroud)
现在,如果我们将它包括两次,我们得到这个:
#ifndef HEADER_H
#define HEADER_H
class MyClass {};
#endif
#ifndef HEADER_H
#define HEADER_H
class MyClass {};
#endif
Run Code Online (Sandbox Code Playgroud)
这是预处理器处理时发生的情况:
#ifndef HEADER_H // HEADER_H is not defined, so we enter the "if" block
#define HEADER_H // HEADER_H is now defined
class MyClass {};// MyClass is now defined
#endif // leaving the "if" block
#ifndef HEADER_H // HEADER_H *is* defined, so we do *not* enter the "if" block
//#define HEADER_H
//
//class MyClass {};
//
#endif // end of the skipped "if" block
Run Code Online (Sandbox Code Playgroud)
因此,最终结果是MyClass只定义了一次,即使标题包含两次.因此生成的代码是有效的.
这是头文件的重要属性.始终定义标题,以便多次包含它们.
这取决于头文件; 对同一文件的多个包含没有语言限制.
某些文件被设计为包含多次(例如,<assert.h>可以多次包含以打开'和'关闭' assert).
许多文件可以安全地被多次包含,因为它们包括防护,其他文件不包括在翻译单元甚至程序中.
include与C或C++语言无关.它是预处理器引入文件的指令.预处理器不关心引入什么文件,也不应该关心.这样做可能完全可以接受:
void Foo::SomeFunc(int cond)
{
switch (cond) {
case kThisCase:
#include "longFirstCase.h"
break;
case kSecondCase:
#include "longSecondCase.h"
break;
case kThirdCase:
#include "longFirstCase.h"
#include "longSecondCase.h"
break;
}
}
Run Code Online (Sandbox Code Playgroud)
我已经多次看到同一个文件作为配置机制.
当然,有很多方法可以将这个例子考虑得更好,但关键是你可能会有很好的理由,因此对使用没有任何限制.
小智 4
可能您的代码周围的 DLLDefines.h 中有一些#define,以防止它被包含两次。
#ifndef DLLDEFINES_H
#define DLLDEFINES_H
// your code
#endif
Run Code Online (Sandbox Code Playgroud)