C++VS2010链接器关于命名空间变量的错误

C++ VS2010 Linker error regarding namespace variables

本文关键字:变量 错误 命名空间 链接 C++VS2010      更新时间:2023-10-16

MyNamespace.h:

namespace MyNamespace{
    int a
}

MyNamespace.cpp:一些使用的函数

main.cpp

#include "MyNamespace.h"
main.obj : error LNK2005: "class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> >
FileNamespace::m_rootDirectoryPath"
(?m_rootDirectoryPath@FileNamespace@@3V?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@A)
already defined in FileNamespace.obj
1>main.obj : error LNK2005: "struct FileNamespace::FileTree FileNamespace::m_dataFileTree"
(?m_dataFileTree@FileNamespace@@3UFileTree@1@A) already defined in
FileNamespace.obj

您在多个翻译单元中定义全局变量(具有外部链接),这会导致重复的定义错误(因为您违反了ODR)。

相反,您应该做的是在标头中用extern声明声明

namespace MyNamespace{
    extern int a;
}

并在单个.cpp文件中定义它(可能在MyNamespace.cpp中)

int MyNamespace::a;

这样,编译器将在单个对象模块中只创建该变量的一个实例,链接器将把其他对象模块中对该变量的所有引用链接到该实例。

注意到这与在标头中声明函数(只在那里编写原型)和定义在单个.cpp中完全等效,这可能有助于您理解问题。

命名空间与其他变量没有什么不同;在标题中,您实际上是在定义"a",而不仅仅是声明它。

在您的标题中:

namespace MyNamespace{
    extern int a;
}

在一个源文件中:

int MyNamespace::a;