Синглтон перевод единицы путаницы - PullRequest
0 голосов
/ 30 мая 2018

В 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), как я могу предотвратить это?

1 Ответ

0 голосов
/ 30 мая 2018

Переменная 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...