1

当我遇到 lnk2005 错误时,我正在使用命名空间。我不知道如何解决这个错误。这是错误:

1>Source.obj : error LNK2005: "int Chart::Bars::d" (?d@Bars@Chart@@3HA) already defined in Chart.obj
1>Source.obj : error LNK2005: "class foo Chart::l" (?l@Chart@@3Vfoo@@A) already defined in Chart.obj
1>Source.obj : error LNK2005: "int Chart::t" (?t@Chart@@3HA) already defined in Chart.obj
1>C:\Users\bnm\dev\examples\play\nmspca\Debug\nmspca.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.49
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

这是代码...

图表.h

#pragma once

#include "foo.h"

namespace Chart
{
    int t;

    foo l;

    namespace Bars
    {

        int d;
    }

}

Foo.h

#pragma once

class foo
{
public:
    int ss;
    char* h;

};

图表.cpp

#include "Chart.h"

using namespace Chart;

int main ()
{
    l.h = "g";
}

源.cpp

#include "Chart.h"

using namespace Chart;

int test()
{
    l.ss = 0;

    return l.ss;
}

当 Source.cpp 中的 #include "Chart.h" 被删除时,问题就消失了。但是,Source.cpp 需要 #include "Chart.h" 来定义命名空间。

在 Chart.cpp 和 Source.cpp 中表达“命名空间图表”的正确方法是什么,以便一切都能编译?

4

3 回答 3

5

如果您在头文件中定义任何对象并将该头文件包含在多个翻译单元中,则这些对象现在会被定义多次。这是你遇到的问题。, 和引入对象的声明t,您已经在头文件中这样做了。ld

支持命名空间范围变量的正确方法是将它们声明为extern在头文件中。这使得它们只是声明而不是定义。然后,在单个实现文件中定义它们。

更改Chart.h为:

#pragma once

#include "foo.h"

namespace Chart
{
    extern int t;

    extern foo l;

    namespace Bars
    {

        extern int d;
    }

}

然后在一个实现文件中,也许Chart.cpp,做:

int Chart::t;
foo Chart::t;
int Chart::Bars::d;
于 2013-02-26T13:59:19.567 回答
2

在您包含 Chart.h 的任何地方,您都有效地将变量 t、l 和 d 放入这些对象中。将它们声明为 extern,然后在 Chart.cpp 中定义它们

于 2013-02-26T13:59:47.417 回答
0

我遇到了完全相同的问题,我发现了一个workarroud。

chart.h 变为:

#pragma once

#include "foo.h"

class Chart{
    static int t;
    static foo l;
    class Bars
    {
        static int d;
    };
};

并在 chart.cpp 中定义变量

int Chart::t;
foo Chart::l;
int Chart::Bars::d;

丑陋,我知道,但至少在需要使用 var 的地方,语法是相同的。

这样,只创建一个 .obj 文件,其中包含防止多重定义错误的变量。
如果您可以在可以解决问题的命名空间上声明一个静态变量,我还没有尝试过。

编辑:

PS这个解决方案在msvc上给出了一些奇怪的错误,好像每次包含它时,代码部分都会引用不同的变量

在我自己的程序上测试了静态内部命名空间,它似乎工作。
示例.h:

namespace sdl{
    static SDL_Surface* screen;

    static int xres = 640;
    static int yres = 480;
    static int bpp  = 32;
    static int flags = SDL_ASYNCBLIT;

};
于 2013-06-04T15:42:28.733 回答