名称空间

时间:2015-10-28 21:46:44

标签: c++

我知道static const class成员只能在标头中初始化。命名空间是否相同?例如,写入是否有效:

namehuman.hpp

namespace namehuman
{
   string const human("human");
}

main.cpp

#include "namehuman.hpp"
cout << namehuman::human << endl;

我想知道包含头文件的所有文件是否都有自己的string人类副本,或者人类是否是真正的全局变量(未多次复制)。为了避免每个包含文件的副本,我是否有义务使用extern

2 个答案:

答案 0 :(得分:6)

常量有内部联系。因此,包含带有常量定义的头的任何编译单元都将拥有自己的对象实例。

根据C ++标准(3.5程序和链接)

  

3具有命名空间范围(3.3.6)的名称具有内部链接(如果是)   

的名称

...

  

- 显式声明为const或的非易失性变量   constexpr既没有明确宣布extern也没有   宣布有外部联系;或

如果需要具有外部链接的常量,则必须使用说明符extern声明它,并在编译单元中定义它。

答案 1 :(得分:1)

我认为这会多次定义human,因此可能会导致ODR违规(见下文)。通常最好只在标题

中声明它
extern const string human;

并将定义添加到实现文件

string human("human");

关闭应用程序时,请注意初始化顺序fiasco和等效项。

当具有外部链接ODR的内联函数使用human时,可能会导致ODR违规。我认为,由于这很容易做到并且没有办法防范它,最好在实现文件中定义常量字符串。