我知道static
const
class
成员只能在标头中初始化。命名空间是否相同?例如,写入是否有效:
namehuman.hpp
namespace namehuman
{
string const human("human");
}
main.cpp
#include "namehuman.hpp"
cout << namehuman::human << endl;
我想知道包含头文件的所有文件是否都有自己的string
人类副本,或者人类是否是真正的全局变量(未多次复制)。为了避免每个包含文件的副本,我是否有义务使用extern
?
答案 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违规。我认为,由于这很容易做到并且没有办法防范它,最好在实现文件中定义常量字符串。