Чем отличаются следующие две версии синглтона Мейера:
Вариант A:
singleton.h
class Singleton {
public:
static Singleton& GlobalInstance();
}
singleton. cpp
Singleton &Singleton::GlobalInstance() {
static Singleton* instance = new Singleton();
return *instance;
}
Вариант B (определение в заголовке):
singleton.h
class Singleton {
public:
static Singleton& GlobalInstance() {
static Singleton* instance = new Singleton();
return *instance;
}
}
Когда я создаю общую библиотеку (g cc 9.2.1), которая использует вариант A, я получу следующие символы:
T Singleton::GlobalInstance()
, а с вариантом BI получу:
u guard variable for Singleton::GlobalInstance()::instance
W Singleton::GlobalInstance()
u Singleton::GlobalInstance()::instance
Я пытаюсь понять, какая здесь точная разница и когда компилятор (g cc) сгенерирует код с переменной guard и его влияние.
Использование нескольких общих библиотек, использующих вариант A или B, дает другое поведение при их динамической загрузке (например, вариант A создает новый экземпляр Singleton в каждой общей библиотеке, в то время как вариант B приведет к общему экземпляру в общих библиотеках, поскольку это слабый символ).
Общая библиотека создается следующим образом:
тест. cpp
* 1 029 *
Компиляция:
g++ -fPIC -c test.cpp singleton.cpp
g++ -shared -o libtest.so test.o singleton.o