Эта реализация хороша, если вы можете ответить на следующие вопросы:
знаете ли вы, когда объект будет создан (если вы используете статический объект вместо нового? У вас есть main ()?)
есть ли у вас синглтон какие-либо зависимости, которые могут быть не готовы к моменту его создания? Если вы используете статический объект вместо нового, какие библиотеки были инициализированы к этому времени? Что ваш объект делает в конструкторе, который может их потребовать?
когда он будет удален?
Использование new () более безопасно, поскольку вы контролируете, где и когда объект будет создан и удален. Но тогда вам нужно удалить его явно, и, вероятно, никто в системе не знает, когда это сделать. Для этого вы можете использовать atexit (), если это имеет смысл.
Использование статического объекта в методе означает, что вы не знаете, когда он будет создан или удален. Вы также можете использовать глобальный статический объект в пространстве имен и вообще избегать getInstance () - он не добавляет много.
Если вы используете потоки, у вас большие проблемы. В C ++ практически невозможно создать пригодный для использования потокобезопасный синглтон из-за:
- постоянная блокировка в getInstance очень тяжелая - полное переключение контекста при каждом getInstance ()
- дважды проверенная блокировка завершается неудачно из-за оптимизации компилятора и модели кеш / слабой памяти, очень сложна в реализации и невозможна для тестирования. Я не буду пытаться делать это в реальной системе, если вы не будете глубоко знать свою архитектуру и хотите, чтобы она не была переносимой
Их можно легко погуглить, но вот хорошая модель слабой памяти: http://ridiculousfish.com/blog/archives/2007/02/17/barrier.
Одним из решений было бы использовать блокировку, но требовать, чтобы пользователи кэшировали указатель, полученный от getInctance (), и были готовы к тому, чтобы getInstance () был тяжелым.
Другим решением было бы позволить пользователям самим управлять безопасностью потоков.
Еще одним решением будет использование функции с простой блокировкой и замена ее другой функцией без блокировки и проверки после вызова new (). Это работает, но полная реализация сложна.