Make shared_ptr не использовать delete
в моем коде мне бы хотелось, чтобы boost:: shared_ptr не вызывал delete, а вызывал вместо него ptr- > deleteMe().
Также у меня есть несколько функций стиля C, которые возвращают ptr. Могу ли я заставить его вызвать lib_freeXYZ (ptr); вместо того, чтобы пытаться удалить?
Ответы
Ответ 1
Или как насчет использования 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) );
Ответ 2
Вы можете предоставить шаблону shared_ptr пользовательскую функцию делетера, которая имеет подпись
void Deleter( T* ptr);
для boost:: 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), см. решение Greg, это очень приятно.
Ответ 3
Дуг Т. хорошо ответил на ваш вопрос. Я расскажу вам об 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);
Ответ 4
Для данных стиля С, сделайте как @Doug. T предложил.
Для вашего класса, почему бы не очистить деструктор? Даже если это включает deleteMe() в деструкторе.