Мы недавно обсуждали эту тему в моем классе EECS. Если вы хотите подробно ознакомиться с примечаниями к лекции, посетите http://umich.edu/~eecs381/lecture/IdiomsDesPattsCreational.pdf.
Есть два способа, как я знаю, чтобы правильно создать класс Singleton.
Первый путь:
Реализуйте это так же, как в вашем примере. Что касается уничтожения, «синглтоны обычно переносятся на протяжении всего времени выполнения программы; большинство ОС восстанавливают память и большинство других ресурсов после завершения программы, поэтому есть аргумент, чтобы не беспокоиться об этом».
Тем не менее, это хорошая практика для очистки при завершении программы. Следовательно, вы можете сделать это с помощью вспомогательного статического класса SingletonDestructor и объявить его своим другом в Singleton.
class Singleton {
public:
static Singleton* get_instance();
// disable copy/move -- this is a Singleton
Singleton(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton& operator=(Singleton&&) = delete;
friend class Singleton_destroyer;
private:
Singleton(); // no one else can create one
~Singleton(); // prevent accidental deletion
static Singleton* ptr;
};
// auxiliary static object for destroying the memory of Singleton
class Singleton_destroyer {
public:
~Singleton_destroyer { delete Singleton::ptr; }
};
Singleton_destroyer будет создан при запуске программы, и "когда программа завершается, все глобальные / статические объекты уничтожаются кодом завершения работы библиотеки времени исполнения (вставленным компоновщиком), поэтому the_destroyer будет уничтожен; его деструктор удалит Singleton, запустив его деструктор «.
Второй путь
Это называется Meyers Singleton, созданный мастером C ++ Скоттом Мейерсом. Просто определите get_instance () по-другому. Теперь вы также можете избавиться от переменной-члена указателя.
// public member function
static Singleton& Singleton::get_instance()
{
static Singleton s;
return s;
}
Это удобно, поскольку возвращаемое значение является ссылкой, и вы можете использовать .
синтаксис вместо ->
доступа к переменным-членам.
«Компилятор автоматически создает код, который сначала создает 's' через объявление, а не после, а затем удаляет статический объект при завершении программы."
Также обратите внимание, что с Meyers Singleton вы «можете попасть в очень сложную ситуацию, если объекты полагаются друг на друга во время завершения - когда Singleton исчезает относительно других объектов? Но для простых приложений это работает хорошо».