Обычный шаблон для одноэлементного класса - что-то вроде
static Foo &getInst()
{
static Foo *inst = NULL;
if(inst == NULL)
inst = new Foo(...);
return *inst;
}
Однако, насколько я понимаю, это решение не является поточно-ориентированным, поскольку 1) конструктор Foo может вызываться более одного раза (что может иметь или не иметь значения), и 2) inst не может быть полностью сконструирован до его возвращения в другая тема.
Одно из решений заключается в том, чтобы обернуть мьютекс вокруг всего метода, но потом я плачу за накладные расходы на синхронизацию еще долго после того, как она мне действительно понадобится. Альтернатива что-то вроде
static Foo &getInst()
{
static Foo *inst = NULL;
if(inst == NULL)
{
pthread_mutex_lock(&mutex);
if(inst == NULL)
inst = new Foo(...);
pthread_mutex_unlock(&mutex);
}
return *inst;
}
Это правильный способ сделать это, или есть какие-то подводные камни, о которых я должен знать? Например, могут ли возникнуть проблемы с порядком статической инициализации, т. Е. Всегда ли гарантируется, что inst всегда будет равен NULL при первом вызове getInst?