我有一个全局变量:
const std::string whiteSpaceBeforeLeadingCmntOption = "WhiteSpaceBeforeLeadingComment";
当我删除此变量声明中的const时,出现以下链接器错误:
error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > whiteSpaceBeforeLeadingCmntOption" (?whiteSpaceBeforeLeadingCmntOption@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A) already defined in REGISTER_TO_UNSRLZ.obj
这是一个.h文件,它包含在各个地方,但我有一个#ifndef带,以避免将它包含在几个地方。任何想法错误是什么?
答案 0 :(得分:5)
当你在.h中有const时,这是有效的,因为const意味着静态,所以你可以在多个compilands中拥有相同的变量。
通过删除.h文件中定义的变量的const,您将在同一程序中创建具有相同标识符的多个实例。
如果你需要删除.h,你可以这样做:
extern std::string whiteSpaceBeforeLeadingCmntOption;
然后:
std::string whiteSpaceBeforeLeadingCmntOption = "";
在你的一个.cpp文件中。
答案 1 :(得分:5)
问题在于,通过在头文件中定义它,它将在包含该头文件的每个编译单元中实例化,从而为链接阶段多次定义。
您要做的是在.h:
中声明extern std::string whiteSpaceBeforeLeadingCmntOption;
然后在单 cpp中声明:
std::string whiteSpaceBeforeLeadingCmntOption = "WhiteSpaceBeforeLeadingComment";
答案 2 :(得分:3)
在C ++中,const对象的名称是它们出现的编译单元的本地名称,或者是#included in。
答案 3 :(得分:2)
#ifndef sentinel只会阻止每个FILE多次包含它。
答案 4 :(得分:1)
因为如果你的标题包含在几个cpp文件中,那么你有多个同一变量的定义(这里是全局的)。这是语言所禁止的。
您想要的是将声明和定义分开:
标题:
extern std::string whiteSpaceBeforeLeadingCmntOption; // declaration
// the 'extern' keyword is here to be sure the linker will look in all cpp for the definition of this variable
在一个cpp中:
std::string whiteSpaceBeforeLeadingCmntOption = "WhiteSpaceBeforeLeadingComment"; // definition
对于类静态变量也是如此。
但是如果对象是const,那么编译器将只生成const对象的一个定义并将其放在只读内存中的某个位置。您不必在巫婆编译单元中指定它。