1

我正在研究我的引擎的核心,我在 Microsoft Visual c++ express 中遇到了严重的链接问题。

为简化起见,导致问题的是这两个头文件,每个头文件都有一个具有不同标识符的命名空间。这两个包含文件实际上是相互包含的。编译没有错误,但是在链接时,显示错误“X 已在 A.obj 中定义”。下面提供了一个示例:

标题 1

#ifndef HEADER1_H
#define HEADER1_H

#include "header2.h"
namespace Core{
    int x, y, z;
}
#endif

标题 2

#ifndef HEADER2_H
#define HEADER2_H

#include "header1.h"
namespace GUI{
    int x, y, z;
}
#endif

最终发生的事情是我收到一条错误消息,指出 x、y 和 z 变量已在创建的第一个 .obj 文件中定义。我假设因为变量来自不同的命名空间,所以它们不会发生冲突。我也有头文件保护,所以头文件似乎没有被多次包含。

无论如何,任何形式的帮助或建议将不胜感激。我已经坚持了大约 3 天:P。另外,如果我没有提供足够的信息,请告诉我,只是我当前的代码非常长。

干杯,乔伊

4

2 回答 2

9

实际上,问题在于变量是在头文件中定义的——不是头文件包含,而是在每个包含头文件的 .cpp 文件中,都定义了所有 6 个变量。

每个 .cpp 文件都变成一个 .o 文件,每个 .o 都以定义的变量结束,这会导致链接器错误。你想要做的是在标题中使用 extern 关键字,它告诉编译器实际变量是在其他地方定义的......

例如:

namespace Core{
    extern int x, y, z;
}

namespace GUI{
    extern int x, y, z;
}

然后,在一个 cpp 文件中(仅在一个 cpp 文件中!)您需要定义不带extern的变量

namespace Core {
    int x, y, z;
}
namespace GUI{
    int x, y, z;
}

这将修复您的链接器错误。

于 2012-04-05T00:41:54.443 回答
1

问题不在于您在多个命名空间中包含相同的变量名称,而在于您在标头中定义变量,而不仅仅是声明它们。这使得编译器为包含头文件的每个编译单元创建这些变量的一个副本,并且这些变量在链接时发生冲突,这就是您得到错误的原因。

使用 extern 仅在标头中声明它们,而不是定义它们:

标题 1

#ifndef HEADER1_H
#define HEADER1_H

#include "header2.h"
namespace Core{
    extern int x, y, z;
}
#endif

标题 2

#ifndef HEADER2_H
#define HEADER2_H

#include "header1.h"
namespace GUI{
    extern int x, y, z;
}
#endif

然后在您的两个标题的相应.cpp文件中,将您的namespace Core { int x, y, z; }namespace GUI{ int x, y, z; }

于 2012-04-05T00:39:05.010 回答