在ContainerTest.h
中,我定义了以下单例类:
class ContainerTest
{
private:
ContainerTest()
{
test = InitializeTest();
}
ContainerTest(const ContainerTest&) = delete;
ContainerTest(ContainerTest&&) = delete;
ContainerTest& operator=(const ContainerTest&) = delete;
ContainerTest& operator=(ContainerTest&&) = delete;
public:
std::vector<uint32_t> test;
static ContainerTest& GetInstance()
{
static ContainerTest rhc;
return rhc;
}
};
我对整个程序中是否仅存在一个ContainerTest实例感到困惑。
即,如果两个cpp文件
A.cpp
和B.cpp
都包含ContainerTest.h
,将创建一个ContainerTest实例,还是两个实例?有人可以解释吗?并且如果创建了两个实例(一个用于A和B的翻译单元),如何防止这种情况发生? 最佳答案
函数中的static
变量将获得一个唯一的符号名称,链接器使用该名称来确保只有一个实例。它将生成一个所谓的弱符号,该弱符号可能会出现在多个翻译单元中。然后,链接器将仅使用一个实例。当嵌入到动态库/共享库中时,这甚至可以工作。
我使用了以下小型测试程序:(主要是您的代码)
#include <vector>
#include <cstdint>
class ContainerTest
{
private:
ContainerTest()
{ }
ContainerTest(const ContainerTest&) = delete;
ContainerTest(ContainerTest&&) = delete;
ContainerTest& operator=(const ContainerTest&) = delete;
ContainerTest& operator=(ContainerTest&&) = delete;
public:
std::vector<uint32_t> test;
static ContainerTest& GetInstance()
{
static ContainerTest rhc;
return rhc;
}
};
int main(int, char**)
{
ContainerTest& ct = ContainerTest::GetInstance();
}
然后用gcc编译,然后我调用:
nm -a libContainerTestSingleton.so |grep rhc| c++filt
提供以下输出:
0000000000000000 b .bss._ZGVZN13ContainerTest11GetInstanceEvE3rhc
0000000000000000 b .bss._ZZN13ContainerTest11GetInstanceEvE3rhc
0000000000000000 u guard variable for ContainerTest::GetInstance()::rhc
0000000000000000 u ContainerTest::GetInstance()::rhc
用
u
标记的符号表示以下含义:(nm联机帮助页)"u" The symbol is a unique global symbol. This is a GNU extension to the
standard set of ELF symbol bindings. For such a symbol the dynamic
linker will make sure that in the entire process there is just one
symbolwith this name and type in use.