Не пытайтесь сделать что-либо, что может удалить указатель, удерживаемый const shared_ptr<T>
, например, вызов reset()
на нем!
Если вы сделаете что-то вроде delete myConstSharedPtr.get();
, delete
будет снова вызываться для сохраненного указателя, когда счетчик ссылок достигнет 0, в основном вызывая двойную бесплатную ошибку.
Кроме того, вы должны пересмотреть свой дизайн и решить, действительно ли вы хотите использовать shared_ptr
.
В конечном счете, в крайнем случае, если константа этого shared_ptr
исходит из внешней библиотеки, которая не должна накладывать это const
ограничение и которую вы не можете должным образом исправить, тогда const_cast
создана для такой ситуации. Но забудьте об этом, вы не хотите использовать это, на самом деле.
Все еще там ? Вот как использовать const_cast
для принудительного сброса const shared_ptr
.
template<typename T>
void forceReset(const std::shared_ptr<T> ptr){
const_cast<std::shared_ptr<T>&>(ptr).reset();
}
ПРЕДУПРЕЖДЕНИЕ: Если этот код на первый взгляд делает то, что вам нужно, это означает, что плохая библиотека, от которой вы зависите, дает утечку памяти. Действительно, невозможно отсоединить shared_ptr
, то есть уничтожить его без обновления счетчика ссылок. Это означает, что если один из общих указателей, ссылающихся на принудительно удаленный ресурс, не будет динамически выделен и никогда не будет удален до конца программы, произойдет двойное освобождение, что приведет к неопределенному поведению... вероятно, к неприятному сбою.
Но если вы все еще хотите продолжить, чего определенно не следует делать, вы можете воспользоваться этим, чтобы предотвратить обнуление счетчика ссылок за счет небольшой утечки памяти, которая будет устранена при выходе из программы. Утечка памяти не приведет к какому-либо неопределенному поведению.
template<typename T>
void forceReset(const std::shared_ptr<T> ptr){
//This leaked shared_ptr will prevent automatic deletion
new std::shared_ptr<T>(ptr);
const_cast<std::shared_ptr<T>&>(ptr).reset();
}
Еще одно предупреждение: я настоятельно не рекомендую никому использовать этот хак. Я дал его, чтобы обсудить риск возиться с умными указателями и const_cast
. Пожалуйста, рассмотрите возможность еще раз исправить проблемную библиотеку или использовать другую.
person
Meatboy 106
schedule
07.01.2020