单身翻译单位混乱

时间:2018-05-30 16:55:09

标签: c++ singleton

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.cppB.cpp都包含ContainerTest.h,那么会创建一个ContainerTest实例,还是两个实例?有人可以解释一下吗?如果创建了两个实例(一个用于A和B&#39的翻译单元),我该如何防止这种情况发生?

1 个答案:

答案 0 :(得分:2)

函数中的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.