Основные различия между этими двумя реализациями:
- первый добавляет избыточный флаг, чтобы сообщить вам, является ли указатель нулевым, и поэтому занимает немного больше памяти, чем нужно;
- второй вообще не синглтон: ничто не мешает
T
иметь открытый конструктор, тем самым нарушая ограничение синглтона.
Основные проблемы с обоимиони (за исключением того факта, что синглтон никогда не является хорошей идеей):
- конструкция не является поточно-ориентированной;вызов
Instance()
из двух потоков может привести к созданию двух объектов; - утечка памяти;они динамически создают объект с помощью
new
, но никогда не вызывают delete
.
В C ++ очень трудно безопасно управлять временем жизни глобально доступного объекта;по этой причине (и многие другие ) я бы порекомендовал вообще избегать анти-паттерна Singleton.Создавайте объекты в хорошо управляемых областях и передавайте ссылки там, где это необходимо.
Если вы действительно хотите глобально доступный экземпляр, то в большинстве случаев самый простой и безопасный вариант:
static Singleton & Instance() {
static Singleton instance;
return instance;
}
Это будет создано при первом вызове функции, и компилятор C ++ 11 должен убедиться, что это потокобезопасно.Оставшаяся проблема заключается в том, что экземпляр может быть уничтожен раньше других статических объектов, что приведет к катастрофе, если его деструкторы попытаются получить к нему доступ.