我有3个cpp文件,看起来像这样
#include "Variables.h"
void AppMain() {
//Stuff...
}
他们都在里面使用相同的变量,所以他们有相同的标题,但我得到像这样的东西
1>OnTimer.obj : error LNK2005: "int slider" (?slider@@3HA) already defined in AppMain.obj
为什么?
答案 0 :(得分:16)
请记住,#include大致类似于剪切和粘贴包含它的源文件中包含的文件(这是一个粗略的类比,但你明白了)。这意味着如果你有:
int x; // or "slider" or whatever vars are conflicting
在头文件中并且该头文件被程序中的三个源文件包含在内,那么它们都将具有一个将被冲突的全局命名x。
你想要做的是将变量定义为extern,以便.cpp文件都将获得声明,然后在一个.cpp文件中给出实际的定义。
在Variables.h中:
extern int x;
在SomeSourceFile.cpp中
int x;
当然,我建议不要使用全局变量,但如果你必须使用它们,这将使它们不会发生冲突。
答案 1 :(得分:3)
因为“int slider”已经在另一个文件中定义了?检查你是否有头部防护......
#ifndef _VARIABLES_H_
#define _VARIABLES_H_
int slider;
#endif
如果它跨越多个翻译单元,并且您确实希望变量不同(即不是全局变量),那么可以在匿名名称空间中声明它们:
namespace {
int slider;
}
如果你确实希望它们具有全球性,那就看看詹姆斯的解决方案。
答案 2 :(得分:3)
这是因为编译器分别编译每个.cpp
文件,为每个文件创建一个.obj
文件。您的标题似乎包含:
int slider;
当这三个.cpp
文件中包含此内容时,您将获得int slider
变量的三个副本,就像您在每个.cpp
变量中声明它一样1}}文件。链接器抱怨这个,因为你没有三个同名的东西。
您可能想要做的是将头文件更改为:
extern int slider;
这告诉编译器某处有一个slider
变量,但可能不在这里,并让链接器弄清楚它。然后,在一个 .cpp
文件中:
int slider;
为链接器提供一个实际变量来链接。
答案 3 :(得分:1)
正在发生的是,Variables.h中的每个变量都为每个单独的c文件提供了全局范围。当链接器编译所有c文件时,它会看到多个具有相同名称的变量。
如果您想将头文件中的变量用作全局变量,则必须在所有变量前面使用关键字“extern”,并且在主文件中不要使用关键字extern。< / p>
主要c:
int n_MyVar;
其他档案:
extern int n_MyVar;
您可以创建两个文件Variables.h和EVariables.h,或者只在main.cpp文件中声明变量。
更好的方法是创建一个Variables类并传递对该类的引用。
答案 4 :(得分:1)
我知道这是一个旧帖子,但我发现这是Google首批搜索结果之一。我通过将变量静态放置来解决问题。
namespace Vert
{
static int i;
}
我尝试了extern,在我的情况下似乎没有解决问题。
答案 5 :(得分:0)
如果通过“Variables.h”多次包含的变量被声明为const,也可以避免这种链接错误。
答案 6 :(得分:0)
虽然我使用extern定义,但我也遇到了这个错误。问题是初始化外部定义中的变量:
ID3D11VertexShader* g_pVertexShader = nullptr;
...
extern ID3D11VertexShader* g_pVertexShader = nullptr; // here's the problem
=&GT;错误
ID3D11VertexShader* g_pVertexShader = nullptr;
...
extern ID3D11VertexShader* g_pVertexShader; // without initializing
=&GT;没有错误,问题解决了