#c #boost #shared-ptr
#c #повышение #общий-ptr
Вопрос:
У меня ситуация, когда мне нужно знать, когда пользователь shared_ptr завершен, то есть когда пользователь, наконец, выпустил все его копии. Обычно здесь просто используется удаление, но в этом случае есть небольшая загвоздка. Базовый объект уже является shared_ptr!
То есть в псевдокоде:
shared_ptr<T> a( new T );
.
.
.
shared_ptr<T> b( a, bind( delete_func, id ) );
Я создаю новую ветку из исходного shared_ptr. Этот новый shared_ptr b
может быть скопирован и использован как обычный shared_ptr, но функция delete_func должна вызываться при выполнении этой конкретной ветви. Теперь я не могу просто использовать a.get()
здесь, поскольку этот новый shared_ptr также должен сохранять базовый объект (это может быть последний shared_ptr для него).
Я ищу какой-то способ сделать это без необходимости кардинально менять структуру. Кто-нибудь видит хорошее простое решение?
Я использую библиотеку boost для интеллектуальных указателей и привязки.
Ответ №1:
Я придумал одно возможное решение.
Создайте функцию удаления следующим образом:
void delete_func( int id, shared_ptr<T> underlying );
Затем, чтобы связать shared_ptr, сделайте это:
shared_ptr<T> b( a.get(), bind( amp;delete_func, id, a ) );
Это создает новый несвязанный shared_ptr с пользовательским удалителем (моя ветвь). Одним из параметров является исходный shared_ptr, поэтому он также должен поддерживать базовый объект shared_ptr. Теперь мне просто нужно немного протестировать это.
Комментарии:
1. Разве это не вызовет удаление, когда последняя копия
b
выйдет из области видимости. Копииa
вполне могут находиться в области видимости в данный момент. — Почему бы просто не добавить пользовательский удалительa
, когда он создается в первую очередь?2. @visitor, это именно то, что требуется. По сути
b
, предполагается, что у него есть собственное время жизни, которое по завершении отменяет регистрацию через удалитель.
Ответ №2:
Я не совсем понимаю, почему вы хотите иметь два отдельных уровня shared_ptr
, почему бы просто не предоставить соответствующий удалитель, который уведомит вас, а затем вызовет checked_deleter
указатель? Таким образом, вам нужен только один удалитель, и вы возвращаетесь к простой проблеме предоставления одного удалителя shared_ptr
.
Комментарии:
1. Считайте, что
a
это часть некоторого внутреннего модуля. Вызывается функция, кa
которой также требуется доступ, но система должна знать, когда этот внешний вызывающий объект завершит ее использование. Таким образом, он не может вернутьсяa
напрямую, поскольку тогда он никогда не узнает, поэтому каким-то образом он должен подключиться к времени жизни этой новой копии переменной.