Сделать shared_ptr не использовать delete
В моем коде я хотел бы, чтобы boost::shared_ptr не вызывал delete, а вместо этого вызывал ptr->deleteMe().
Также у меня есть несколько функций в стиле C, которые возвращают ptr. Могу ли я сделать это вызов lib_freeXYZ(ptr); вместо того, чтобы пытаться удалить?
4 ответа
Или как насчет использования stl для предоставления функтора обертки - описание Doug T., но без пользовательского вызывающего.
boost::shared_ptr<T> ptr( new T, std::mem_fun_ref(&T::deleteMe) );
boost::shared_ptr<S> ptr( new S, std::ptr_fun(lib_freeXYZ) );
Вы можете дать шаблон shared_ptr пользовательскую функцию удаления, которая имеет подпись
void Deleter( T* ptr);
для повышения::shared_ptr
Так что для Deleter вы бы сделали
boost::shared_ptr<T> ptrToT( new T, Deleter );
затем в теле Deleter:
void Deleter( T* ptr);
{
ptr->deleteMe();
// And make sure YOU ACTUALLY DELETE (or do whatever else you need to
// do to release the resource)
delete ptr;
}
Для вашего конкретного случая, когда вам нужно что-то простое (например, ptr->deleteMe), смотрите решение Грега, это очень приятно.
Дуг Т. приятно ответил на ваш вопрос. Я расскажу вам о intrusive_ptr. Может быть, вы тоже можете использовать его в своем проекте.
Если у вас есть библиотека C, в которой уже есть счетчик ссылок, но вам нужно вручную вызывать эти функции, вы можете использовать boost::intrusive_ptr
и предоставить правильные определения для его функций add_ref и release. intrusive_ptr найдет и вызовет их. Они несут ответственность за увеличение количества ссылок и уменьшение его, освобождая ресурс при необходимости:
void intrusive_ptr_add_ref(foo *f) {
lib_add_ref(f);
}
void intrusive_ptr_release(foo *f) {
if(lib_dec_ref(f) == 0)
lib_free(f);
}
Тогда вы можете просто создавать объекты из необработанных указателей типа foo*
, intrusive_ptr будет вызывать ваши функции при копировании / уничтожении:
intrusive_ptr<foo> f(lib_alloc());
// can wrap raw pointers too, which already may be referenced somewhere else
foo *p = get_foo_from_somewhere();
function_taking_intrusive_ptr(p);
Для данных в стиле C сделайте как @Doug. Т предложил.
Для вашего класса, почему бы не сделать уборку в деструкторе? Даже если это включает deleteMe() в деструкторе.