首先,在现代 C++ 编译中,您可以使用 #pragma once 代替包含防护。
然后,您的示例有点混乱,因为您在标题中定义了 extern 函数。通常include 文件用于定义函数的声明,而不是函数的定义。
如果你在你的头文件中定义了函数,并且如果这个头文件被多个CPP源文件使用,这个函数将被定义多次同名,并且程序链接时会出错!
更好的包含是
#ifndef HEADER_FILE
#define HEADER_FILE
int two(void);
#endif
或
#ifndef HEADER_FILE
#define HEADER_FILE
static int two(void) { return 2; }
#endif
或
#pragma once
static int two(void) { return 2; }
在最后一种情况下,函数two()定义在每个包含该头文件的CPP源文件中;但是这个函数是静态的,所以CPP源编译正确,CPP程序链接没有问题。
在你的问题中,你问
在这种情况下我们也可以忘记添加#define HEADER_FILE?
就个人而言,我在非常特殊的棘手情况下使用相同的标题。
以下 2 个包含是一个“好”的示例:
/*******************************************************************
* XTrace.Configuration.h
********************************************************************
*/
#pragma once
#define MODULEx(n) extern StructDefineMODULE MODULE_##n;
#include "XTrace.Modules.h"
#undef MODULEx
#define MODULEx(n) { #n, &MODULE_##n } ,
static struct ModuleTRACE tModuleTrace[]
= {
#include "XTrace.Modules.h"
{ 0, 0 }
};
XTrace.Modules.h 包含在哪里
/*******************************************************************
* XTrace.Modules.h
********************************************************************
*/
MODULEx( BBDIXFILE )
MODULEx( CECHO )
MODULEx( INITDBFIELD )
MODULEx( IVIRLUX )
第一个包含包含 #pragma once 并调用相同的内部包含 2 次。
第一次调用定义StructDefineMODULE结构的extern声明。
第二次被调用来初始化一个ModuleTRACE结构数组。
由于此包含被调用了 2 次,因此必须避免使用 #pragma once 或 #ifndef。
在使用内部包含时,我确信 100% 用于定义 StructDefineModule 的所有元素也用于初始化 tModuleTrace[] 数组。
包含内部结果,将是
/*******************************************************************
* XTrace.Configuration.h
********************************************************************
*/
#pragma once
extern StructDefineMODULE MODULE_BBDIXFILE;
extern StructDefineMODULE MODULE_CECHO;
extern StructDefineMODULE MODULE_INITDBFIELD;
extern StructDefineMODULE MODULE_IVIRLUX;
static struct ModuleTRACE tModuleTrace[]
= { { "BBDIXFILE" , &MODULE_BBDIXFILE }
, { "CECHO" , &MODULE_CECHO }
, { "INITDBFIELD" , &MODULE_INITDBFIELD }
, { "IVIRLUX" , &MODULE_IVIRLUX }
, { 0, 0 }
};
我希望这可以帮助您理解为什么在某些情况下可以避免包含守卫!