которые любят спрашивать "а зашем":
Допустим, я создал и использовал в нескольких местах переменную в качестве shared, но потом я решил, например, сохранить ее в массиве, где, тоже например, хранятся другие уникальные значения данного типа, которые не предполагается использовать больше нигде, кроме как не через сам массив.
Ну и насколько это вообще оправдано? Кастить общую к уникальной?
что таоке shared переменная
только копированием разадресованного объекта в новый и помещение в unique_ptr
shared_ptr, так сложно?
То есть мне ФИЗИЧЕСКИ придется сделать его полную копию и использовать ее уже на свое усмотрение, а старую reset-нуть?
положи не сам объект в поинтер, а специальную обертку над ссылкой на этот объект, которая когда тебе надо bool=false и не удаляет
Прямого преобразования из shared_ptr в unique_ptr нет
а то что ты собрался делать прям крутая вещь...
К сожалению, я уже понял
Ограничить использование ресурса? А в чем проблема?
Причины тоже понятны?)
я предложил нормальное решение, обертка
Переместите, это разумнее, эффективнее и лучше отражает семантику кода (перемещаем значения из шаренной области в уникальную, а не магически превращаем одно в другое)
Не понял, то есть вы предлагаете мне сразу использовать unique? А если придет (из библиотеки, например) shared, то что делать? Как быть с функциями, которые используют данное значение (принимают shared)?
Подумать, нужен ли unique_ptr вообще, раз библиотека возвращает shared_ptr
Подумал, нужна - что дальше?
Объясните, зачем?)
Я предлагаю что-то вроде: auto shared = make_shared<Foo>(/* ... */); // ... auto unique = make_unique<Foo>(std::move(*shared)); Ещё лучше, конечно же, с самого начала оперировать уникальным указателем, ведь его всегда можно преобразовать в shared
Как минимум, чтобы иметь доступ к ним строго из одного места, не допуская, например, случайной очистки (например, другим программистом) Я понимаю, что в реальной разработке это маловероятно, однако, меня вообще не интересуют вопросы причин. Хочется больше поговорить о следствиях, даже и тем более если мы говорим о плохих последствиях
Их семантика различна. Уникальный указатель сильнее ограничивает программиста, выражая тем самым больше гарантий. Уникальный указатель строго лучше всегда, когда может быть использован
Разочаровывает, что, насколько я понимаю, shared будет ссылаться на те же самые данные. Жаль, что нет метода leave или около того
Кажется, вопрос был не о разнице между unique и shared...
О контроле в том числе. Shared принадлежит нескольким (ну, логично), а unique можно контролировать в одном конкретном месте (потоке исполнения, если угодно)
Ответ на "зачем" – чтобы лучше выразить эту самую семантику в своём коде
Согласен, но раз библиотека использует shared в том числе во вспомогательных функциях - нецелесообразно изобретать трудности для самого себя
Я уже предложил оставить данный вопрос: так всем будет проще. Мне просто интересно, где бы это могло пригодится. А не использовать это всегда успеем
Честно говоря, я не вполне понял смысл первого предложения, так что мне трудно прокомментировать его
Насколько я понимаю, данное предположение auto shared = make_shared<Foo>(/* ... */); // ... auto unique = make_unique<Foo>(std::move(*shared)); Никак не касается блока, на который ссылается САМ shared для контроля. То есть, мы все также сможем использовать shared (совместно с unique), что может повлечь лишние проблемы. Ну, это если я все правильно понял и код можно исполнить (в том или ином виде, но с тем же смыслом)
Я бы сделал попытку донести до авторов библиотеки, что предоставлять пользователю unique_ptr обычно предпочтительнее, ведь иногда мы способны повлиять на используемую библиотеку
Ну, в мире github можно использовать issue, насколько я помню. А там уже предложить изменения, но это ванильный вариант
Все shared будут теперь указывать на некоторый пустой объект, не связанный с unique Но ведь это и не страшно, поскольку данный shared должен быть последним, если мы хотим поддержать семантику, конвертировав его в unique и он вместе с пустым объектом умрёт в текущем скоупе. Если же он был не последним – вы где-то запутались в собственных рассуждениях и преобразование shared_ptr в unique_ptr – не то, что вы на самом деле хотите
Ну, и стоит заметить, что вопросы, связанные с deleter я опустил в данном примере
Я не знаю, как компилятор разрешает подобные ситуации. ``` Если же он был не последним – вы где-то запутались в собственных рассуждениях и преобразование shared_ptr в unique_ptr – не то, что вы на самом деле хотите ``` Я могу запутаться и без этого 'если'
Про это я пока не слышал (мне уже написали, постараюсь покапать по данной теме)
Я думаю, что стоит немного поэкспериментировать на простых примерах и после этого только рассматривать свой, более сложный реальный случай
Где-то чуть раньше я писал, что это чисто теоретические рассуждения. Я хочу узнать, стоит ли позволять приводить тип shared к unique В данный момент я изучаю контроль памяти, для меня это впервые и тема достаточно интересная На stackoverflow есть интересный, но нечеткий вопрос: можно ли заменить ВСЕ указатели в коде на умные? То есть, вообще все, а те, что приходят извне - оборачивать в умные
Можно, но не нужно
Потому что unique используется в основном в скоупах или для полного владения над объектом? Я просто сам хочу ответить себе на этот вопрос
Потому что шаред имеет оверхед, как по производительности, так и по семантике
По семантике я бы это ко всем умным указателям отнес
Указатель, ведущий себя как невладеющая ссылка, которую можно ребиндить
Обсуждают сегодня