shared_ptr и dynamic_cast
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 01.01.21 16:09
Оценка:
Здравствуйте!

Использую shared_ptr, а точнее — QSharedPointer, но думаю, что принципы не сильно отличаются.
Делаю dynamic_cast от того указателя, который хранится в QSharedPointer.

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

Вижу проблему, что с точки зрения языка и среды выполнения это вроде как два разных указателя, но счётчик-то у них должен быть общий. Наверняка этот вопрос кто-то прорабатывал, просто я не в курсе

Пните в нужном направлении плс
Маньяк Робокряк колесит по городу
Re: shared_ptr и dynamic_cast
От: reversecode google
Дата: 01.01.21 16:27
Оценка: +2
ничего не понятно
но dynamic_pointer_cast еще со времен C++11 завезли
Re: shared_ptr и dynamic_cast
От: Alexander G Украина  
Дата: 01.01.21 17:07
Оценка: 9 (2)
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>Использую shared_ptr, а точнее — QSharedPointer, но думаю, что принципы не сильно отличаются.

M>Делаю dynamic_cast от того указателя, который хранится в QSharedPointer.

Вдобавок к уже данному ответу, у QSharedPointer есть qSharedPointerDynamicCast.

Но вообще главное, что у shared_ptr на все такие случаи есть это aliasing constructor.
(8) на cppreference.
template< class Y >
shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept;


С его помощью можно сделать и dynamic_pointer_cast, и your_custom_cast, и указатель на член объемлющей структуры, разделяющий счётчик с основным указателем.

В QSharedPointer, похоже его не завезли, так что там только частное решение.
Русский военный корабль идёт ко дну!
Re[2]: shared_ptr и dynamic_cast
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 01.01.21 17:34
Оценка: -2
Здравствуйте, Alexander G, Вы писали:

M>>Использую shared_ptr, а точнее — QSharedPointer, но думаю, что принципы не сильно отличаются.

M>>Делаю dynamic_cast от того указателя, который хранится в QSharedPointer.

AG>Вдобавок к уже данному ответу, у QSharedPointer есть qSharedPointerDynamicCast.


Предыдущий оратор метнул ссылку, и был таков. Он видимо думает, что я в состоянии сейчас сам разбираться с этим вопросом

Спасибо за довольно развёрнутый ответ. Как минимум, по сравнению с предыдущим

В догонку вопрос — не встречал на русском ничего на эту тему, чтобы попроще было разжеваноизложено?
Маньяк Робокряк колесит по городу
Re[3]: shared_ptr и dynamic_cast
От: Alexander G Украина  
Дата: 01.01.21 17:56
Оценка: 4 (1)
Здравствуйте, Marty, Вы писали:

M>В догонку вопрос — не встречал на русском ничего на эту тему, чтобы попроще было разжеваноизложено?


Перевод поста Энтони Вильямса про aliasing constructor https://habr.com/ru/post/263751/

Там только о подобъекте, правда.

Но касты тоже через него можно сделать, и они так и делаются, как видно в исходниках буста:
https://github.com/boostorg/smart_ptr/blob/856ed108e885fffbdcc4c8e89cce7082d330aef6/include/boost/smart_ptr/shared_ptr.hpp#L907-L915

Ну или MSVC STL:
https://github.com/microsoft/STL/blob/2914b4301c59dc7ffc09d16ac6f7979fde2b7f2c/stl/inc/memory#L2130-L2140
Русский военный корабль идёт ко дну!
Re: shared_ptr и dynamic_cast
От: 3V Россия  
Дата: 02.01.21 13:02
Оценка: +3
Здравствуйте, Marty, Вы писали:

M>Пока использую его локально, и храню голеньким, но задумался о более длительном его хранении и передаче в разные места. И хочется тоже хранить его в каком-то шареде.


Сначала не понял чего ты хочешь.
Потом вроде понял.
У тебя есть QSharedPointer<Base>, ты хочешь получить из него
QSharedPointer<DerivedFromBase>, который бы разделял владение с
первоначальным объектом?

Если да, то у QSharedPointer есть
QSharedPointer<X> dynamicCast() const


З.Ы. Еще напомню что в Qt есть
QSharedData, QSharedDataPointer и QExplicitlySharedDataPointer — это
если тебе нужен COW (автоматически или руками).

З.З.Ы. Еще. Сорцы Qt доступны. Там все просто.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.