Russian Qt Forum
Ноябрь 23, 2024, 19:17 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 ... 3 4 [5] 6   Вниз
  Печать  
Автор Тема: Qt + вумные указватели  (Прочитано 30683 раз)
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #60 : Февраль 25, 2020, 16:17 »

Код
C++ (Qt)
template<class T>
struct CItemRef {
...
// data
 std::shared_ptr<T> m_shared;
 std::weak_ptr<T> m_weak;
 T * m_raw;
};
typedef CItemRef<TreeItem> TreeItemRef;
 
И вроде это даже thread-safe. Или нет? Покритикуйте

И что есть что?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #61 : Февраль 25, 2020, 17:19 »

И что есть что?
Код
C++ (Qt)
template<class T>
struct CItemRef {
 CItemRef( std::shared_ptr<T> sh )  :
   m_weak(sh),
   m_raw(sh.get())
 {
 }
 
 T * data( void ) const
 {
   auto p = m_shared.get();  // locked?
   if (p) return p;
 
   if (m_raw)
     assert(!m_weak.expired());
 
   return m_raw;
 }
 
...
// data
 std::shared_ptr<T> m_shared;
 std::weak_ptr<T> m_weak;
 T * m_raw;
};

Edit: убрал "ненужные тонкости" в конструкторе
« Последнее редактирование: Февраль 26, 2020, 10:37 от Igors » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #62 : Февраль 25, 2020, 17:44 »

Код
C++ (Qt)
template<class T>
   m_shared.reset();
 

Не понял
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #63 : Февраль 26, 2020, 10:44 »

Не понял
shared не заполняем, он только для лока. Померещилось что шаред аргумент может меняться, но это не так - он подается по значению. Исправил

Конечно можно обойтись и без члена шаред, напр метод lock возвращает шаред, но класс его не хранит. Дело вкуса, мне больше нравится так, класс "самодостаточен", никакие др вумники (снаружи) не привлекаются.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #64 : Февраль 26, 2020, 15:41 »

Код
C++ (Qt)
template<class T>
   auto p = m_shared.get();  // locked?
   if (p) return p;
 
 }
 

Тогда m_shared всегда содержит 0.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #65 : Февраль 26, 2020, 15:50 »

Тогда m_shared всегда содержит 0.
Не тормозите
Код
C++ (Qt)
bool Lock( void )
{
 if (!m_shared.get())
  m_shared = m_weak.lock();
 
 return m_shared.get();
}
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #66 : Февраль 26, 2020, 18:05 »

ОК, след вопрос, откуда мы возьмем шаред, если вы хотите удалять по raw-указателю?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #67 : Февраль 27, 2020, 11:20 »

ОК, след вопрос, откуда мы возьмем шаред, если вы хотите удалять по raw-указателю?
Из самого айтема, шаред или в паренте или (для рута) m_self
Код
C++ (Qt)
struct CIem {
...
 
private:
TreeItemRef m_parent;
std::vector<std::shared_ptr<CItem>> m_children;
std::shared_ptr<CItem> m_self;    // not null for root
};
Не зациклится ли деструктор? Ну по-любому, даже в худшем случае, это решается через custom deleter. Но думаю (не проверял) этой проблемы не возникнет вообще. Когда шаред удаляет данные (нет больше владельцев), он сначала должен поставить указатель на данные = 0 (чтобы никто не успел схватить), а потом звать deleter. Поэтому когда дело дойдет до деструктора m_self - он уже нулевой.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #68 : Февраль 27, 2020, 11:37 »

Ну ладно, а что все-таки "отдавать наружу" чтобы удобно было там его юзать? Может так
Код
C++ (Qt)
TreeItemRef item = treeView->Root().childAt(0);
 
item.SetName("test");
if (CheckSomething(item))
DeleteItem(item);
 
if (!item.IsNull())
item.SetName("done");
 
if (item.Lock()) {
...
}

Но weak_ptr тоже будет неудобен и громоздок. Нужен "сахар", обертки, и все такое

То Вы чай без сахара пьёте, то Вам weak_ptr громоздкий Улыбающийся.

Код
C++ (Qt)
if (auto item_data = item.lock())
{
   item_data->doSomething();
   ...
}
Что тут громоздкого?
Записан

Пока сам не сделаешь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #69 : Февраль 27, 2020, 12:55 »

Код
C++ (Qt)
if (auto item_data = item.lock())
{
   item_data->doSomething();
   ...
}
Что тут громоздкого?
Да все. Невдобняк капитальный. Ведь вся содержательная часть - вызовы типа doSomething, все должно быть заточено под них. А тут мне надо заводить еще переменную, и/или как-то группировать по локу и.т.п. - та ну нафиг

И, как ни странно, мне кажется это куда менее "безопасным". Застрянет где-то item_data - и я могу долго парить айтемы что уже обречены.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #70 : Февраль 27, 2020, 13:15 »

И, как ни странно, мне кажется это куда менее "безопасным". Застрянет где-то item_data - и я могу долго парить айтемы что уже обречены.

А с item.Lock()/Unlock() меньше возни и никогда ничего не застрянет Улыбающийся. И item.data() в Release сборке никогда не вылетит. Ну дело хозяйское.
Записан

Пока сам не сделаешь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #71 : Февраль 28, 2020, 07:44 »

А с item.Lock()/Unlock() меньше возни и никогда ничего не застрянет Улыбающийся.
Возни не меньше, но самих item.Lock()/Unlock() гораздо меньше, т.к. они делаются только по моему желанию
И item.data() в Release сборке никогда не вылетит.
Вылет - случай не такой уж плохой по сравнению с "молотит полную фигню" или "тормозит". Бездумный lock() провоцирует такие тяжелые ошибки.

В общем, не все так просто как пишут в книжках  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #72 : Февраль 28, 2020, 09:36 »

В общем, не все так просто как пишут в книжках  Улыбающийся
Я не знаю какие книжки вы читаете, но непросто становится, когда делают какую-то дичь, как в данном случае.

Нельзя удобно совместить обычные и умные указатели, никак.
Если переделывать дерево, то shared_ptr для этого замечательно подходит. И позволяет закрыть все юзкейсы, которые вы здесь пытаетесь решить через жопу.
Также несложно будет сделать дерево, с которым можно будет безопасно работать из разных потоков.
« Последнее редактирование: Февраль 28, 2020, 12:11 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #73 : Февраль 29, 2020, 11:14 »

Выдохлись Улыбающийся Попробую подвести некоторые итоги.

Значит удалять айтем (имея вумный указатель на него) нечем, стандартные средства этого не обеспечивают, придется великом.

Может это единственная проблема? Думаю что нет. У меня немало случаев когда голые указатели на айтемы хранятся в мапе как key или value. Не вижу как менять их на вумные (какие ?). Ну ясно шаред сразу разрушает весь ф-ционал. К сожалению, не проходит и weak. Даже если перетерпеть занудный лок - сравнение мапы перестанет работать. Остается "фиговый листочек" обсервер - ну, мягко говоря, несолидно

Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #74 : Февраль 29, 2020, 12:01 »

Выдохлись Улыбающийся Попробую подвести некоторые итоги.
Просто не забывайте вдыхать. Улыбающийся

Значит удалять айтем (имея вумный указатель на него) нечем, стандартные средства этого не обеспечивают, придется великом.
Это не откуда не следует. Откуда этот глупый вывод?

Может это единственная проблема?
Проблемы есть исключительно у вас, в связи с непониманием работы умных указателей.

Ну ясно шаред сразу разрушает весь ф-ционал. К сожалению, не проходит и weak.
Какой функционал разрушает шаред? Каким образом? Улыбающийся
Почему не проходит и weak? Для чего он должен пройти? Улыбающийся

Как обычно, было сделано куча глупых выводов на основании своей безграмотности. Улыбающийся

Ну что, "деревянным айтемом" мы опять обсудили, предлагаю переходить к очередному обсуждению undo или финдреплейс. Давненько не возвращались. Улыбающийся
Записан
Страниц: 1 ... 3 4 [5] 6   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.307 секунд. Запросов: 23.