.obj 中已经定义的变量;这里发生了什么?

Variable already defined in .obj; What is going on here?

head.h


#pragma once

namespace foo
{
    int bar;

    int funct1();
}

head.cpp

#include "head.h"

int foo::funct1()
{
    return bar;
}

main.cpp

#include <iostream>

#include "head.h"


int main()
{
    foo::bar = 1;
    std::cout << foo::funct1() << std::endl;
    return 0;
}

错误 LNK2005 "int foo::bar" (?bar@foo@@3HA) 已在 head.obj

中定义

我不明白这是怎么回事。我试着寻找答案,但每个人的问题都针对他们的代码,甚至看起来都不像我遇到的问题。

我没有将 .cpp 文件包含到 main 中。我没有重新定义任何东西。我实际上只是将 1 分配给变量,然后使用同一命名空间中的函数返回它。怎么会被多次定义?

head.h 包含在 main.cpp 和 head.cpp 中。 所以变量被定义了两次。

可能的解决方案:使其内联。 "extern" 解决方案也不错,尽管方法较旧。

namespace foo
{
    inline int bar;
}

header head.h 包含在两个编译单元 head.cppmain.cpp 中。所以变量bar被定义了两次。您可以通过以下方式声明没有定义的变量

#pragma once

namespace foo
{
    extern int bar;

    int funct1();
}

然后在一些cpp模块中定义它。

这个foonamespace-levelbar声明:

namespace foo
{
    int bar;
}

实际上是一个定义.

要使其成为声明,请在 head.h:

中将 bar 标记为 extern
namespace foo
{
    extern int bar;
}

然后在head.cpp中定义:

int foo::bar = 0;

How is it being defined multiple times?

它在 head.cpp 中定义一次,在 main.cpp 中定义一次。总共是两次。这违反了一个定义规则,即每个变量只能有一个定义。

int bar;

这是一个变量的定义。您已将其包含在两个翻译单元中。

可以在外部声明中声明一个没有定义的变量:

extern int bar;

用这样的声明替换定义,并将定义放入恰好一个翻译单元。

I am not redefining anything. I am literally just assigning 1 to the variable

您正在重新定义变量!

head.cpp 通过 #include "head.h" 有一个,main.cpp 通过 #include "head.h".

有一个

你需要在header中merely declare it(不寻常但也不算太奇怪):

extern int bar;

…然后在一个翻译单元中定义它。这就像您对 static class 成员所做的一样(尽管语法略有不同)。

自 C++17 起,you may do this by instead plopping the inline keyword on to your definition.

或者,避免可变全局变量……

请注意 foo 不是 class,而是命名空间。当您在 header 文件中声明一个自由变量时:

int bar;

然后多次 #include 这个 header 文件(到不同的 CPP 文件中,导致多个翻译单元编译),你会得到一个链接器错误。每个人都知道。

并且,您将在声明中添加 extern 属性,并在 CPP/C 文件之一的其他位置 定义 变量。

将全局变量放入命名空间只不过是给 global 变量一个不同的名称。想想如果 foo::barfoo__NS__bar,因此你必须在 header 中添加 extern 并且 define foo::bar 在一些定位。

请注意,这与 class 的 non-static 成员变量不同。 class 变量不需要这样 defined/declared 因为 class 是 类型 。 class-type 的每个实例化变量都有一个单独的变量副本。 此外,当您在 class 中添加一个 static 变量时,您在逻辑上给那个 global 变量另一个名称。因此,您必须static-variable 定义 CPP 文件之一。