包括Guards和#ifndef #define预处理语句

时间:2013-11-24 19:20:27

标签: c++ ifndef

如果我执行以下操作:

dConst.hpp

const int POWER_LEVEL = 9001;

genPower.hpp

#include "dConst.hpp"

#ifndef GENPOWER_HPP
#define GENPOWER_HPP

const int GENERATOR[1] = { POWER_LEVEL };

#endif

对于使用生成器数组常量的任何代码,我最终都会遇到链接器错误。

但是,如果我用代码块切换#include "dConst.hpp"

#ifndef GENPOWER_HPP
#define GENPOWER_HPP

它有效......

我是否滥用#ifndef的力量?

2 个答案:

答案 0 :(得分:1)

未充分利用 #ifndef的力量。

您的dConst.hpp文件需要包含警卫。否则,如果它包含在翻译单元中的多个文件中,则会导致问题(您看到的确切问题)。

编辑:我还会在您的包含声明之前将genPower.hpp中的包含警卫放在文件顶部。

答案 1 :(得分:1)

是的,当然。

包含警卫的要点是确保你的代码不会被包含两次 - 如果你的头文件中有一些不在包含守卫内的代码,如果你包括那个标题两次,你就是在外面定义所有内容守卫两次。

为了更好地了解正在发生的事情,您生成的代码看起来像这样:

#include基本上只是将包含文件的内容直接插入到另一个文件中,这意味着你的genPower.hpp看起来像这样(没有正确的包含保护,就像你最初在你的问题中一样):

const int POWER_LEVEL = 9001;

#ifndef GENPOWER_HPP
#define GENPOWER_HPP

const int GENERATOR[1] = { POWER_LEVEL };

#endif

因此,每次包含该文件时,在到达#ifndef之前,都会定义POWER_LEVEL。如果你用#ifndef / #define切换POWER_LEVEL行,每次包含这个文件时,它首先会检查它是否已被包含(使用#ifndef - 如果它已被包含,#define应该完成它的工作)并且只有这一点(一旦它被发现这是第一次)它将定义POWER_LEVEL。

此外,你几乎肯定也希望在你的dConst.hpp上包含警卫 - 所有标题都应该包含警戒,并且他们应该在头文件中保护一切。这是#ifndef的错误。