Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 命名空间中的常量全局变量_C++ - Fatal编程技术网

C++ 命名空间中的常量全局变量

C++ 命名空间中的常量全局变量,c++,C++,我知道staticconstclass成员只能在标题中初始化。名称空间也是这样吗?例如,写入以下内容是否有效: namehman.hpp namespace namehuman { string const human("human"); } #include "namehuman.hpp" cout << namehuman::human << endl; main.cpp namespace namehuman { string const human

我知道
static
const
class
成员只能在标题中初始化。名称空间也是这样吗?例如,写入以下内容是否有效:

namehman.hpp

namespace namehuman
{
   string const human("human");
}
#include "namehuman.hpp"
cout << namehuman::human << endl;
main.cpp

namespace namehuman
{
   string const human("human");
}
#include "namehuman.hpp"
cout << namehuman::human << endl;
#包括“namehuman.hpp”

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

根据C++标准(3.5程序和链接)< /P> 3具有名称空间作用域(3.3.6)的名称在以下情况下具有内部链接: 姓名

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


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

我认为这将多次定义
human
,因此可能会导致ODR冲突(见下文)。通常最好只在标题中声明它

extern const string human;
并将定义添加到实现文件中

string human("human");
关闭应用程序时,请小心初始化顺序失败和类似情况


当带有外部链接ODR的内联函数使用
human
时,可能会导致ODR冲突。我认为,因为这很容易做到,而且没有办法防止它,所以最好在实现文件中定义常量字符串。

尽管将多次定义
human
,但这不是ODR冲突,因为定义具有内部链接。您建议的更改,不清楚是否是改进,甚至可能会减慢代码的速度;弗洛里安,因为虽然你的代码“有效”,但这是一个错误的答案(顺便说一句,我没有投反对票)。请看另一个答案。我说过这可能会导致ODR冲突:如果内联函数访问存储在
human
中的字符串,则使用ODR,但如果使用ODR,则要求只有一个定义。这不会导致ODR冲突。每个翻译单元的
是一个不同的对象,每个这样的对象只有一个定义。(参见[basic.link]/2,内部链接的定义是其他单位的名称不能引用它)@M.M,这正是问题所在。如果内联函数根据转换单元使用不同的对象,则会出现ODR冲突。(请参见[basic.dev.odr]/3,每个程序应包含该程序中使用的每个非内联函数或变量的一个定义。)