我正在开展一个需要以下结构的项目:
2个CPP文件包含类,这些类需要H文件1中的裸函数。类和nakeds需要H文件2中的变量。
我可以拆分CPP文件,以便它们使用包含nakes及其所需变量的2个单独文件。但我更喜欢使用这种结构。
看起来编译器跳过#ifndef命令,我对问题进行了测试:
主:
#include <iostream>
//1>CPPFile2.obj : error LNK2005: "bool Test1" (?Test1@@3_NA) already defined in CPPFile1.obj
//1>CPPFile2.obj : error LNK2005: "bool Test2" (?Test2@@3_NA) already defined in CPPFile1.obj
int main()
{
}
CPPFile 1:
#include <iostream>
using namespace std;
#include "HFile1.h"
CPPFile 2:
#include <iostream>
using namespace std;
#include "HFile2.h"
HFile 1:
#include "HFile2.h"
#pragma once
#ifndef Name1
#define Name1
//Use test1, this workes fine
//Use test2, this workes fine
#endif
HFile 2:
#pragma once
#ifndef Name2
#define Name2
bool Test1 = false;
bool Test2 = false;
#endif
#ifndef #define #endif结构怎么可能无法正常工作?
答案 0 :(得分:6)
你的问题是第二个标题是定义变量,而不只是声明它们。程序中必须有一个定义,因此编译失败。这与包括警卫无关,因为包含警卫仅在单个翻译单元内保护。在您的情况下,每个.cpp文件都包含标题,因此分别定义相同的变量。
解决方案是仅声明标头中的变量,并在单个翻译单元中定义它们:
#ifndef Name2
#define Name2
extern bool Test1;
extern bool Test2;
#endif
// single .cpp
bool Test1 = false;
bool Test2 = false;
虽然整个事情都有一些代码味道。您可能希望重新设计您的解决方案。在大多数情况下,使用全局变量不是一个好的解决方案。
答案 1 :(得分:3)
您收到链接错误;这与包括警卫无关。您已在两个目标文件中定义了Test1
和Test2
。相反,您需要确保只有一个目标文件定义它而另一个extern
它。
答案 2 :(得分:1)
永远不要在标题中定义变量..你应该在.cpp中定义它,然后如果你想从另一个.cpp文件访问它,就创建一个带有'extern'的标题。
File1.cpp
bool Test1 = false; //define a var in your .cpp
File1.h
extern bool Test1; //extern it in your header
File2.cpp
#include "File1.h" //include the header of the variable
void Somefunction()
{
if (Test1) //use the variable
{
//someting
}
}
然而,使用全局变量通常是一种不好的做法......