如果我执行以下操作:
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
的力量?
答案 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的错误。