Pull to refresh

Comments 18

Что-то я ничего не понял.
Что за множество одиночек?
Как правило одиночки должны жить на протяжении жизни всего приложения, поэтому они и создаются, зачем их в течении жизни создавать и уничтожать? оО
В приложении существовало большое количество одиночек — классы, отвечающие за ведение лога, загрузку ресурсов, вывод звука. Даже класс с основной логикой приложения был Singleton. А уничтожать их нужно для того, потому что профилировщик видел new без delete и считал все выделенное одиночками утечкой.
Так были ли утечки или так считал только профилировщик?
Конечно были) Просто их трудно было найти из-за того, что профилировщик выводил информацию о них в общий список с ругательствами на память, выделенную Singleton'ами. В результате получалось около 10 тысяч сообщений. В общем, довольно проблемная была система. Когда же удалось разобраться с одиночками, осталось несколько сотен реальных проблем.
UFO just landed and posted this here
Так конечно правильно, но всё равно, это не окончательное решение проблемы. Поскольку статические члены удаляются в порядке, обратном тому, в котором они были созданы, возможна ситуация обращения к уже удалённому статическому члену.
Как это не static. Тогда бы вообще механизм не работал. Я привел пример реализации метода, чтобы показать что использовался не такой подход
Singleton* Singleton::getInstance() {
      static Singleton instance;
      return &instance;
}

То, что метод статический, указывается в заголовочном файле. Я его не приводил, посчитав, что интерфейс Singleton'a уже всем давно примелькался)
UFO just landed and posted this here
Интерфейс реализации не содержит
class Singleton
{
public static Singleton* getInstance();
//…
}
А пример в статье уже из соответствующего cpp-файла
UFO just landed and posted this here
Да, со стековым проблем с псевдоутечкой не было бы. Но осталась бы проблема взаимосвязи. Чтобы обеспечить удаление стековых элементов в заданном порядке, придется создать их в обратном порядке, т.е где-то нужно будет записать что-то типа
Singleton1::getInstance();
Singleton2::getInstance();
//....
SingletonN::getInstance();

Это позволит рассчитывать, что при завершении работы будет удален сначала SingletonN, потом Singleton[[N-1]] и так далее. Но если, например, в деструкторе Singleton1 будет вызов Singleton2::getInstance, то все может и упасть. Кроме того, вызов getInstance только ради того, чтобы обеспечить правильный порядок разрушения похож скорее на костыль, делающий невозможным создание при первом использовании (например, если за время работы приложения Singleton1 ни разу не пригодился, то логично вообще не создавать его экземпляр).
UFO just landed and posted this here
Вот и я к тому же выводу пришел. Иногда этот паттерн помогает, но основывать на нем всю архитектуру явно не стоит.
Я, конечно, не архитектор, но Великая Сила подсказывает мне, что если код заточен на порядок удаления синглтонов — то что-то не так в архитектуре. И, скорее всего, синглтонов здесь не должно быть вообще.

p.s: синглтон уже достаточно давно считается антипаттерном, и надо стараться избегать его использование.
UFO just landed and posted this here
Он не пострадал. Его книга вспомнилась из-за восстания удаленных классов. А так он сам и писал, что одного правильного решения, как удалять Singleton классы не существует — все по ситуации.
Не надо их удалять. И вообще, не стоит их много создавать. Один два синглтона на приложение хватит. Можно еще thread_local заюзать и будет по синглтону на поток. Что может быть удобно.
Как вариант, можно создавать и разрушать синглтоны (в правильном порядке) в одном месте — в конструкторе и деструкторе, соответсвенно, вспомогательного класса, создав его глобальный статический экземпляр:

class SingletonOwner
{
public:
    SingletonOwner()
    {
        Singleton0::instance();
        Singleton1::instance();
        Singleton2::instance();
        ...
    }
    ~SingletonOwner()
    {
        Singleton0::instance()->free();
        Singleton1::instance()->free();
        Singleton2::instance()->free();
        ...
    }
};

...
static SingletonOwner singletonOwner;
...

Sign up to leave a comment.

Articles