Почему бы вам не использовать ссылки на интеллектуальные указатели?

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

Спасибо за разъяснение

Ответ 1

Предполагая, что вы говорите о shared_ptr здесь...

Это просто из-за использования ссылка умного указателя после его уничтожили?

Это хороший ответ. Вы можете не знать абсолютно время жизни указателя, на который ссылается ваша ссылка.

Чтобы обойти это, вам нужно посмотреть в boost:: weak_ptr. Он не участвует в подсчете ссылок. Когда вам нужно использовать его, он дает вам shared_ptr, который уходит после вашего завершения. Он также сообщит вам, когда будет собрано ссылка на указатель.

Из weak_ptr документация

Шаблон класса weak_ptr хранит "слабая ссылка" на объект, который уже управляемый shared_ptr. к доступ к объекту, слабый_ptr может быть преобразован в shared_ptr, используя shared_ptr конструктор или член функция блокировка. Когда последний shared_ptr на объект уходит и объект удаляется, попытка получить shared_ptr от weak_ptr экземпляры, ссылающиеся на удаленные объект не будет выполнен: конструктор будет выбросить исключение типа boost:: bad_weak_ptr и weak_ptr:: lock вернет пустой shared_ptr.

Обратите внимание, что метод expired() также скажет вам, находится ли ваш ptr.

Ответ 2

При использовании интеллектуальных указателей (или любого объекта управления распределением) вы рассчитываете на поведение, определенное в конструкторе/деструкторе, для управления refs/derefs/locks/unlocks. В результате эти типы объектов должны быть истинными объектами для правильной работы. при использовании ссылок на такие объекты (или указатели) вы обходите механизм (и запрашиваете клинг).

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

У нас есть настраиваемые интеллектуальные контроллеры, и мы всегда привыкли передавать "const refsomething &"

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

Ответ 6

Передача ссылки на интеллектуальный указатель на функцию абсолютно безопасна и является хорошей идеей. Объект может исчезнуть, но умный указатель не будет, он будет сидеть там, указывая нуль, по крайней мере, до тех пор, пока функция не вернется. Это лучший способ сглаживания интеллектуального указателя в пределах его возможностей. Если вы используете ссылку с модификатором const по тому, на что она ссылается, тогда у вас есть интеллектуальная ссылка для наблюдения:

const smart_ptr<T>&

Интересно и полезно, что const запрещает вам использовать ссылку, чтобы сказать, нул умный указатель и удалять объект, но он не останавливает первоначальный интеллектуальный указатель от обнуления, и ваша ссылка будет отражать это изменение.

Возвращение ссылки на интеллектуальный указатель из функции запрашивает всевозможные проблемы.