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

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

Страниц: 1 2 [3] 4 5 ... 9   Вниз
  Печать  
Автор Тема: C++ Object Token Library  (Прочитано 58874 раз)
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


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


я правильно тебя понял:
ты хочешь унаследоваться от shared, что бы отрубить шаринг?
Совершенно правильно

это типа как...

унаследоваться от торговца, что бы отрубить ему торговлю?
унаследоваться от самолета, что бы отрубить ему возможность летать?
Да, именно так. Возможность летать мне не только не нужна, но даже вредит. Мне нужен только weak т.е. (хочу ползать Улыбающийся) возможность наблюдать не сдох ли. Зияющая дыра в std: почему я не могу получить weak от "юника"?  Это ведь никак не менее usable.

ты никогда не думал о том, почему юник называется "юником" ?

никогда не думал о том, что если тебе не нужно летать,
тогда тебе просто не нужно использовать самолет?


никогда не думал о том,
что для того что бы ползать,
совсем необязательно наследоваться от самолета
и ломать наследнику крылья?

у тебя точно всё впорядке с логикой?
Абсолютно (чувачок)  Улыбающийся

заметно.






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

Сообщений: 3260


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

Этот момент отнюдь не бесспорен/очевиден. "Продление жизни" может быть чревато самыми неприятными последствиями, напр если shared агрегирован, ведь для владельца все уже свершилось, он полагает что агрегированный уже сдох.

Этот момент действительно неочевиден, но является единственным решением проблемы.
Где например используется QPointer в Qt? Ну какая-нибудь вьюха, наверное (код не смотрел) хранит QPointer на модель - модель удалили, вьюхе пофигу, она и так проверяет указатель на nullptr. Ровно тоже самое можно сделать на shared_ptr - нет никакой причины почему вьюхи не должны "шаредно" владеть моделью.
У QPointer есть юзкейзы, но они настолько редкие что добавлять это в стандартную библиотеку нафиг не уперлось (то есть в той же Qt QPointer юзается ровно по той причине что все виджеты в главном потоке и "продлять жизнь" не надо). Но ВНЕЗАПНО не все с++ погромисты пишут ГУИ тулкит и не у всех есть требование "только в главном потоке".
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


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

Чем спорить, кто shared, а кто ресурс, я бы предложил составить UML диаграмму классов. Но кто ж будет заниматься такой ерундой Улыбающийся.

Да, UML рулит и механизма сделать агрегацию 1к1 в с++ нет. Точнее это будет 0/1 к 1 (указатель). Конечно, есть пресловутый not_null (а также мембер "по значению" для композиции) но это все не унифицированно/нестандартизировано.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

никогда не думал о том,
что для того что бы ползать,
совсем необязательно наследоваться от самолета
и ломать наследнику крылья?
В текущей реализации std - увы, обязательно. Никаких др способов получить weak нет.

ты никогда не думал о том, почему юник называется "юником" ?
Утверждается что владелец один (и только один). И что? Почему я не могу иметь любое число weak ("потребителей")?  Уникальности (единственности владения) это никак не противоречит.

У QPointer есть юзкейзы, но они настолько редкие что добавлять это в стандартную библиотеку нафиг не уперлось
Не сказал бы что редки, QPointer - вещь вполне приличная, но она "интрузивна" (quard'ы хранятся в QObject), a std такого принципиально не признает.

нет никакой причины почему вьюхи не должны "шаредно" владеть моделью.
Хотя я тоже не могу сходу назвать причину, такой подход следует признать легкомысленным. Shared не то чтобы "редкий случай", но не такой уж и частый, не так уж много активных классов шарится. Думаю что лепить его типа "да вроде проходит" не надо.

Кстати - а почему внутри классов Qt вумные указатели юзаются редко, полно "голых"? Объяснения типа "ну это ж legacy", тем более "да они не знают" явно несостоятельны.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

Утверждается что владелец один (и только один). И что? Почему я не могу иметь любое число weak ("потребителей")?  Уникальности (единственности владения) это никак не противоречит.
Потому что weak на unique никому не нужен, у нас нет возможности продлить жизнь ресурса, которым управляет этот юник. Что должен делать weak на unique? Как он может помещать разрушить ресурс, которым управляет юник, из другого потока?
Вам Аварон об этом уже несколько раз написал.
Как только вы попробуете решить эту проблему юника, то у вас сразу получиться shared.
« Последнее редактирование: Февраль 09, 2020, 09:24 от Old » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

У QPointer есть юзкейзы, но они настолько редкие что добавлять это в стандартную библиотеку нафиг не уперлось
Нет у него юзкейсов даже в Qt. Улыбающийся
Его поведение со всеми его ограничениями легко реализуется например так:
Код
C++ (Qt)
void Bar::setResource( MyResource *res )
{
 m_res = res;
 connect( m_res, QObject::destroyed, [&]( QObject * ){ m_res = nullptr; } );
}
 

А дальше проверяй на не null.
« Последнее редактирование: Февраль 09, 2020, 10:02 от Old » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



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

Да, именно так. Возможность летать мне не только не нужна, но даже вредит. Мне нужен только weak т.е. (хочу ползать Улыбающийся) возможность наблюдать не сдох ли. Зияющая дыра в std: почему я не могу получить weak от "юника"?  Это ведь никак не менее usable.

ты никогда не думал о том, почему юник называется "юником" ?

никогда не думал о том, что если тебе не нужно летать,
тогда тебе просто не нужно использовать самолет?

Хотите сказать, что не может существовать такая пара unique-weak, в которой weak становится expired, когда unique помирает?

Потому что weak на unique никому не нужен, у нас нет возможности продлить жизнь ресурса, которым управляет этот юник. Что должен делать weak на unique? Как он может помещать разрушить ресурс, которым управляет юник, из другого потока?
Вам Аварон об этом уже несколько раз написал.
Как только вы попробуете решить эту проблему юника, то у вас сразу получиться shared.

Продление жизни ресурса - это отдельный случай. То, что во время доступа через weak всё может грохнуться, если в это время в другом потоке unique удалит объект, не мешает иметь возможность expired для weak (Smart observers to use with unique_ptr). Равно как и weak для unique вообще, это вопрос терминологии. Голый указатель, полученный из unique_ptr::get(), вполне себе weak для unique, со своими особенностями.

Далее, можно разделять композитную агрегацию, когда объект-часть может входить в состав только одного объекта-целого одновременно, и временный доступ к этому объекту для чтения его данных/вызова методов, когда время его жизни будет продлено. Это опять же, вопрос терминологии.

Да, UML рулит и механизма сделать агрегацию 1к1 в с++ нет. Точнее это будет 0/1 к 1 (указатель). Конечно, есть пресловутый not_null (а также мембер "по значению" для композиции) но это все не унифицированно/нестандартизировано.

Вот я и попытался это классифицировать и унифицировать. Кстати, голый указатель C++ тоже распознается и участвует в библиотеке как токен, и можно получить его характеристики Подмигивающий.
Записан

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

Сообщений: 3260


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

Объяснения типа "ну это ж legacy", тем более "да они не знают" явно несостоятельны.

И тем не менее это так https://lists.qt-project.org/pipermail/development/2020-January/038544.html
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


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

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

смахивает на какой то бред.

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

ты никогда не думал о том, почему юник называется "юником" ?
Утверждается что владелец один (и только один). И что? Почему я не могу иметь любое число weak ("потребителей")?  Уникальности (единственности владения) это никак не противоречит.

в том то и дело, что противоречит.

ты вообще понимаешь, как работают с weak?

конкретно, ответь на вопрос:
почему напрямую через weak нельзя получить доступ к ресурсу,
а вместо этого приходится сначала расшаривать владельца?

Код:
#include <iostream>
#include <memory>

struct data
{
    int val = 333;
};

std::shared_ptr<data> holder = std::make_shared<data>();
 
int main()
{
    std::weak_ptr<data> weak = holder;
   
    // так нельзя
    // std::cout << "value = " << weak->val << '\n';
   
    // нужно сначала расшарить ресурс:
    std::shared_ptr<data> owner = weak.lock();     
    std::cout << "value = " << owner->val << '\n';
}

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

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

однако в случае с unique_ptr, создание второго владельца противоречит самой идее существования юника.
хочешь рассшаривать - используй shared_ptr,
и не морочь голову ни себе, ни людям.


резюмируя:

если ты - наркоман, который не дружит с головой, тогда вот тебе твой weak специально для юника:

Код:
auto* weak1 = smart.get();
auto* weak2 = smart.get();
auto* weak3 = smart.get();

но если ты дружишь с головой, то ты понимаешь:
грамотный weak должен быть безопасным.
а безопасным он может только и только если гарантируется,
что ресурс не будет освобожден.

такие гарантии предоставляет shared_ptr

любая попытка сделать безопасный weak для юника приведет к тому,
что из юника получится shared

Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


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

Хотите сказать, что не может существовать такая пара unique-weak, в которой weak становится expired, когда unique помирает?

хочу сказать, что невозможно организовать безопасный доступ к ресурсу юника через weak,
не сделав при этом сам юник шаредом.
« Последнее редактирование: Февраль 09, 2020, 17:41 от _Bers » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

гарантировать безопасность
..
безопасность
..
безопасность
..
Используйте конкретный термин "not thread-safe" - ведь именно его Вы имели ввиду. Даже если бы это и было так, это не может быть основанием "невозможности", просто пишем что данный класс/фича "not thread-safe", и спокойно ее юзаем. Да, если дело дойдет до multi-threading - придется прилагать усилия, лочить и.т.п. Но это обычная работа которую приходится делать во многих случаях, нередко и с "продленным" weak.

хочешь рассшаривать - используй shared_ptr,
и не морочь голову ни себе, ни людям.
Эту песню я слышал много раз.
Код:
Голые указатели = плохо. Давайте сделаем все указатели вумными! И будет счастье! 
Ну а поскольку возможности юника на практическом нуле - остается делать все shared. Вас не смущает что это чисто ход мысли начинающего? Что давать такие советы не требует никакого (ну совсем никакого) ума? Вы сами-то пробовали так делать? И что, хорошо получилось? Может лучше поменять взад на голые?  Улыбающийся

Да, и чисто технически "продлить юник" несложно. Причем используя совершенно легальные средства предоставляемые std. Несколькими постами выше ViTech кинул ссылочку, интересно - почитаете.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



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

хочу сказать, что невозможно организовать безопасный доступ к ресурсу юника через weak,
не сделав при этом сам юник шаредом.

А для однопоточного случая?

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

Пока сам не сделаешь...
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


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

А для однопоточного случая?

не плоди сущности без необходимости.

Код:
auto* weak = unique.get();
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



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

не плоди сущности без необходимости.

Код:
auto* weak = unique.get();

И где тут "weak становится expired, когда unique помирает"?
Записан

Пока сам не сделаешь...
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


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

И где тут "weak становится expired, когда unique помирает"?

зачем он нужен?
« Последнее редактирование: Февраль 10, 2020, 11:56 от _Bers » Записан
Страниц: 1 2 [3] 4 5 ... 9   Вверх
  Печать  
 
Перейти в:  


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