链接器对此报告重复的符号:#ifndef testttt#define testtttvoid anything(){ std::cout<<"hellooooooo";}#endif因为它在include防护内部,所以我希望此函数只定义一次。但显然不是。我知道我可以static在它前面加上这个词,然后它就会起作用(我仍然觉得很讽刺,因为应该将static赋予它内部链接,但是可以从多个cpp文件中使用该函数)。因此,我想我的问题分为两部分:1)为什么包含保护不像其他标头项那样阻止该函数的多个定义,以及2)为什么static当应该假定静态名称阻止名称可见时,单词会解决此问题吗?在其他翻译单位中?我添加了它,实际上可以从包含此头文件的任何位置调用此函数。
3 回答
皈依舞
TA贡献1851条经验 获得超3个赞
“ 1)为什么包含保护不能像其他标题项那样阻止该功能的多个定义”
因为每个翻译单元(即.cpp文件)都是分别处理的,并且要经过相同的条件。翻译单元不会共享其他翻译单元遇到的预处理器定义。这意味着将处理该标头的所有翻译单元都将包含该函数的定义。当然,链接器随后会抱怨同一函数具有多个定义。
“ 2)当应该使用静态词来防止名称在其他翻译单元中可见时,为什么静态词会解决此问题?”
因为static
关键字为每个翻译单元制作了该功能的私有副本。
但是,如果您希望在共享头文件中定义该函数,则应将其标记为inline
,这将解决您的问题并使不必要的预处理器防护。
潇湘沐
TA贡献1816条经验 获得超6个赞
1)为什么包含保护不能像其他标题项那样阻止该功能的多个定义,
包含保护可防止在同一转换单元中多次包含标头。但是,它不能防止出现多个定义:如果标头包含在多个翻译单元中,则将存在多个定义错误,因为该函数是在每个翻译单元中定义的,并且由于它具有外部链接,因此所有翻译单元都可以请参阅所有其他翻译单元的定义。为防止发生此错误,您只需在标头中提供声明,并在一个文件中提供定义.cpp。
阅读有关一个定义规则(ODR)和外部链接的信息。
2)当应该使用静态词来防止名称在其他翻译单元中可见时,为什么静态词会解决此问题?
因为static使函数在每个翻译单元内部均有效。这就是内部链接的含义:其他翻译单元看不到定义。
- 3 回答
- 0 关注
- 426 浏览
添加回答
举报
0/150
提交
取消