【发布时间】:2019-11-05 00:24:33
【问题描述】:
假设我有一个头文件,并假设复制宏已得到处理: f1.h:
Object& getObject() {
static Object obj;
return obj;
}
在包含此标头的任何地方,翻译单元都将拥有自己的 obj 副本。那么,如果a.cpp、b.cpp、c.h包含这个header,obj会被实例化3次?
现在,如果我有以下内容:
f2.h:
Object& getObject();
f2.cpp:
#include <f2.h>
Object& getObject() {
static Object obj;
return obj;
}
在这种情况下,我的标头被包含在内,但符号仅在 cpp 文件中创建。因此,链接器只找到在 cpp 文件中创建的单个静态 obj 对象,而每个引用 .h 文件的翻译单元都获得该符号?
这是对正在发生的事情的正确直觉,还是这里有更多的作用?
【问题讨论】:
-
“在任何包含这个头的地方,翻译单元都会有自己的obj副本。” 这个假设是错误的。该对象将被创建一次且仅一次。在头部的函数定义前加上
inline,以避免函数的多个定义。 -
您知道如果在标题右侧定义方法时不使用 inline 关键字,尝试此操作会遇到问题吗?
-
如果函数在头文件中定义,并且不是内联的,它将在包含该头文件的每个编译单元(又名源文件)中定义。所以程序不会链接 - 函数是否有静态变量。如果函数是内联的,则实现(可能是编译器,也可能是链接器)将解决问题 - 再次,无论函数是否具有静态。
标签: c++ static linker translation-unit