C++ c++;:如何访问同一命名空间中但定义在不同文件中的变量?

C++ c++;:如何访问同一命名空间中但定义在不同文件中的变量?,c++,namespaces,extern,C++,Namespaces,Extern,考虑以下两个文件: a、 cpp: #include <string> namespace a { const std::string str = "something"; } 我收到链接器错误: /usr/bin/ld: /tmp/ccEtAgEb.o: in function `main': b.cpp:(.text+0x10): undefined reference to `a::str[abi:cxx11]' collect2: error: ld returne

考虑以下两个文件:

a、 cpp:

#include <string>
namespace a
{
    const std::string str = "something";
}
我收到链接器错误:

/usr/bin/ld: /tmp/ccEtAgEb.o: in function `main':
b.cpp:(.text+0x10): undefined reference to `a::str[abi:cxx11]'
collect2: error: ld returned 1 exit status
有人能告诉我为什么,以及如何修复它吗?我希望避免在头文件中引用a::str,因为它不是公共接口的一部分,而是命名空间中的一个私有变量

const std::string str = "something";
应该是

extern const std::string str = "something";
const
限定命名空间范围内的对象具有在其名称上施加内部链接的附加属性。您的原始代码与相同

static const std::string str = "something";
应该是

extern const std::string str = "something";
const
限定命名空间范围内的对象具有在其名称上施加内部链接的附加属性。您的原始代码与相同

static const std::string str = "something";
尝试在b.cpp中添加#include“a.cpp”。 然后您的代码将是正确的,外部定义在b中,实现在a中。

尝试将#include“a.cpp”添加到b.cpp中。
然后您的代码将是正确的,外部定义在b中,实现在a中。

Re:“我想避免在头文件中引用
a::str
,因为它不是公共接口的一部分”:——头文件几乎总是包含不属于公共接口的信息。类定义中的私有成员是最明显的例子。如果您没有将其放在标题中,并且出于某种原因决定更改命名空间或
字符串
对象的名称,则必须查找使用该名称的每个位置并进行更改。@PeteBecker没有找到,谢谢,因此您可以将其放在私有标题中。Re:“我想避免在头文件中引用
a::str
,因为它不是公共接口的一部分“:--头文件几乎总是包含不属于公共接口的信息。类定义中的私有成员是最明显的例子。如果您没有将其放在标题中,并且出于某种原因决定更改命名空间或
字符串
对象的名称,则必须查找使用该名称的每个位置并进行更改。@PeteBecker没有找到,谢谢,因此您可以将其放在私有标题中。如果我在a.cpp中将“const”更改为“extern const”,我们仍然没有a::str的定义,并且仍然存在链接器错误。在进一步测试中,如果我同时从a.cpp和b.cpp中删除“const”,它将正常工作。所以我就这么做了。@EricSokolowsky-不,不是用。你很可能在其他地方做错了什么。我用默认编译器(9.3.0版)尝试了你的链接,确实有效。然而,当我在那个网站上尝试使用GCC9.2.0时,我确实得到了一个链接器错误。但据我所知,如果对a::str的所有引用都是“extern”(这些只是声明),那么定义在哪里?@ericsoklowsky-也适用于9.1。请注意,我们必须手动添加“b.cpp”作为附加参数。当您切换编译器时,该字段被重置。在这里,如果我将a.cpp中的“const”改为“extern const”,它就会起作用,我们仍然没有a::str的定义,并且仍然存在链接器错误。在进一步测试中,如果我同时从a.cpp和b.cpp中删除“const”,它将正常工作。所以我就这么做了。@EricSokolowsky-不,不是用。你很可能在其他地方做错了什么。我用默认编译器(9.3.0版)尝试了你的链接,确实有效。然而,当我在那个网站上尝试使用GCC9.2.0时,我确实得到了一个链接器错误。但据我所知,如果对a::str的所有引用都是“extern”(这些只是声明),那么定义在哪里?@ericsoklowsky-也适用于9.1。请注意,我们必须手动添加“b.cpp”作为附加参数。当您切换编译器时,该字段被重置。它在这里工作