Деструктор при использовании синглтона
Пусть есть синглтон класс
class Singleton {
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};
А реализация такова:
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance () {
if (_instance == 0) {
_instance = new Singleton;
}
return _instance;
}
Если мы для него опишем деструктор :
Singleton :: ~Singleton(){
delete _instance;
}
то получается, что при завершении любой функции(при выходе из области видимости), которая обращалась с сущности синглтон и сохарняла указатель, будет вызывать деструктор, который удалит объект.
Вопрос - как быть? Реализовывать свой hsared_ptr или что-то подобное внутри деструктора это такой себе вариант,как мне кажется, а терять глобальный объект, который нужен 1 на всё время работы программы вообще нельзя
Ответы (1 шт):
Вы зовете delete в двух местах, и в обоих местах он лишний. Функция, обращающаяся к синглтону, не должна его звать, потому что кому-то после нее он может понадобиться.
Деструктор синглтона не должен звать delete, тут вообще логика задом наперед. delete зовет деструктор (и освобождает память), а не наоборот. Если звать delete из деструктора, то деструктор позовется дважды, а это - неопределенное поведение.
Вообще, это плохой синглтон, как минимум потому что не потокобезопасный. Хороший выглядит так:
class Singleton
{
public:
static Singleton &Instance()
{
static Singleton ret;
return ret;
}
private:
Singleton();
};
И писанины меньше.
Тут деструктор вызывается один раз при выходе из программы (и если вы его напишете, там не нужен никакой delete, конечно).
Использовать new имеет смысл только если вы наоборот хотите, чтобы деструктор синглтона не вызывался на выходе из программы. (Обычно деструкторы не делают ничего такого важного, без чего нельзя закрыть программу, и для скорости может хотеться их не звать.)
Но тогда нужно написать так, чтобы было потокобезопасно:
static Singleton &Instance()
{
static Singleton &ret = *new Instance;
return ret;
}
И опять же, delete тут не нужен.