Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Singleton и shared_ptr  (Прочитано 9066 раз)
0 Пользователей и 1 Гость смотрят эту тему.
AlexCasual
Помогающий

by
Offline Offline

« : 02-05-2014 14:50 » 

Есть класс singleton, его instance реализован через shared_ptr :

Код:

public:
static CObject* Instance()
{
if (!_instance)
{
_instance.reset(new CObject());
}
return _instance.get();
}

private:
static std::shared_ptr<CObject> _instance;

Вызывается CObject::Instance() из разных мест в коде...

Вопрос : безопасно ли вот так использовать shared_ptr в singleton? Наткнулся на ситуацию, когда при удалении одного класса удалился и shared_ptr<CObject>, хотя он мне ещё нужен был...
Как вообще компилятор определяет в каком месте кода именно нужно удалить shared_ptr?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 02-05-2014 15:57 » 

Делай лучше так:

Код: (C++)
#include <iostream>

using namespace std;

class C
{
private:
        C()
        {
                cout << "C::C" << endl;
        }
        C(const C &other) {}
        ~C()
        {
                cout << "C::~C" << endl;
        }
public:
        static C &Instance()
        {
                cout << "Enter C::Instance" << endl;
                static C instance;
                cout << "Leave C::Instance" << endl;
                return instance;
        }
        void f()
        {
                cout << "C::f" << endl;
        }
};

int main()
{
        cout << "Enter main" << endl;
        C::Instance().f();
        C::Instance().f();
        cout << "Leave main" << endl;
        return 0;
}
Enter main
Enter C::Instance
C::C
Leave C::Instance
C::f
Enter C::Instance
Leave C::Instance
C::f
Leave main
C::~C
Статическая переменная внутри статического метода инициализируется "лениво" - при первом входе, и затем существует до конца работы программы. В конце вызывается деструктор.
« Последнее редактирование: 02-05-2014 15:59 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
AlexCasual
Помогающий

by
Offline Offline

« Ответ #2 : 02-05-2014 17:39 » 

Мне желательно через указатели,а не ссылки...
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 02-05-2014 17:54 » 

AlexCasual, ну замени ссылку на указатель в типе результат Instance и в операторе return добавь взятие адреса. В чём проблема?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
AlexCasual
Помогающий

by
Offline Offline

« Ответ #4 : 03-05-2014 11:12 » 

Проблема,наверное,больше архитектурная...У меня есть singleton A и singleton B, в деструкторе A я вызываю методы B, и в один прекрасный момент получается, что B уже разрушен (произвольнео удаление статических переменных)...Вот такие вот дела =(
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #5 : 03-05-2014 11:23 » 

В чистом  С++ не предусмотрен сборшик мусора и тому подобное. Следовательно не бывает "чудес" по типу, она само удалилось или удалится. Надо смотреть исходники и искать, где вообше происходит удаление объекта из кучи.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
AlexCasual
Помогающий

by
Offline Offline

« Ответ #6 : 03-05-2014 11:54 » 

Finch, я думаю, что в моем случае проще и надежнее все управление объектами взять на себя и сделать функцию Release(), которую вызвать там, где надо...это правда не сильно красиво(
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 03-05-2014 12:37 » 

AlexCasual, зачем в деструкторе синглетона что-то вызывать? Когда заведомо известно, что синглетон уничтожается после окончания работы программы, когда состояние прочих статических объектов неопределённое? Разумеется нужен Release, вызываемый до завершения работы программы, когда состояния объектов гарантированно существуют.

Другой вариант: вложить экземпляр B внутрь A (сделать композицию), и управлять жизнью B из A, раз это так надо.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines