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

时间:2019-06-24 11:01:08

标签: c++ variables c++14 declaration definition

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;
}

在head.obj中已经定义的错误LNK2005“ int foo :: bar”(?bar @ foo @@ 3HA)

我不知道发生了什么。我尝试寻找答案,但是每个人的问题都针对他们的代码,甚至看起来都不像我遇到的问题。

我没有将.cpp文件包含到main中。我没有重新定义任何内容。我实际上只是将1分配给变量,然后在同一名称空间中使用函数将其返回。如何多次定义?

7 个答案:

答案 0 :(得分:5)

标头head.h包含在两个编译单元head.cppmain.cpp中。因此,变量bar被定义了两次。您可以按照以下方式声明没有定义的变量

#pragma once

namespace foo
{
    extern int bar;

    int funct1();
}

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

答案 1 :(得分:4)

foo命名空间级别的bar声明:

namespace foo
{
    int bar;
}

实际上是定义

要使其声明,请在 head.h 中将bar标记为extern

namespace foo
{
    extern int bar;
}

然后在 head.cpp 中定义它:

int foo::bar = 0;

答案 2 :(得分:2)

head.h包含在 main.cpp和head.cpp中。 因此变量定义了两次。

可能的解决方案:使其内联。 “外部”解决方案也不错,尽管方法较旧。

namespace foo
{
    inline int bar;
}

答案 3 :(得分:2)

  

如何多次定义?

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

int bar;

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

可以在外部声明中声明变量而无需定义:

extern int bar;

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

答案 4 :(得分:2)

  

我没有重新定义任何内容。我只是在给变量赋1

您正在重新定义变量!

#include "head.h"具有一个通孔main.cpp,而#include "head.h"具有一个通孔extern int bar;

您需要在标题中merely declare it(不寻常,但不太奇怪):

static

...然后以一个翻译单位进行定义。就像您对Error in if (!all(pars < 1e-06)) pars[pars < 1e-06] <- 0 : missing value where TRUE/FALSE needed 类成员所做的一样(尽管语法稍有不同)。

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

或者,避免使用可变的全局变量……

答案 5 :(得分:1)

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

int bar;

然后多次#include此头文件(到不同的CPP文件中,导致多次翻译单元编译),您将收到链接器错误。每个人都知道。

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

将全局变量放入命名空间只不过是为 global 变量指定了其他名称。考虑一下foo::bar是否为foo__NS__bar,因此必须在标题中添加extern,并在某些地方 define foo::bar

请注意,这与类的非静态成员变量不同。由于类是类型,因此不需要以这种方式定义/声明类变量。每个类类型的实例化变量将具有该变量的单独副本。 除此之外,当您在类中添加static变量时,您将为逻辑上 全局变量赋予另一个名称。因此,您必须在CPP文件之一中定义该静态变量

答案 6 :(得分:0)

问题是您在header.h和main.cpp中多次定义了foo :: bar。这是一个全局变量,已经定义了多次,这是不可能的。因此,链接器抱怨您多次定义它。

您可以通过使用extern声明foo :: bar来解决此问题:

namespace foo
{
    extern int bar;

    int funct1();
}

然后在header.cpp中定义它:

int foo::bar;