hacer que shared_ptr no use delete

en mi código, me gustaría que boost :: shared_ptr no llame a delete pero llame a ptr-> deleteMe () en su lugar.

También tengo algunas funciones de estilo C que devuelven un ptr. ¿Puedo hacer que se llame lib_freeXYZ (ptr); en lugar de tratar de eliminar?

O qué tal si usamos stl para proporcionar el functor contenedora – descripción de Doug T. pero sin la persona que llama personalizada.

boost::shared_ptr ptr( new T, std::mem_fun_ref(&T::deleteMe) ); boost::shared_ptr ptr( new S, std::ptr_fun(lib_freeXYZ) ); 

Puede darle a la plantilla shared_ptr una función de eliminación personalizada que tiene la firma

  void Deleter( T* ptr); 

para un impulso :: shared_ptr

Entonces, para Deleter harías

  boost::shared_ptr ptrToT( new T, Deleter ); 

luego en el cuerpo de 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; } 

Para su caso específico cuando necesita algo simple (como ptr-> deleteMe) vea la solución de Greg, es muy agradable.

Doug T. respondió a tu pregunta muy bien. Te contaré sobre intrusive_ptr. Quizás también puedas usarlo en tu proyecto.

Si tiene alguna biblioteca en C que ya tiene recuento de referencias, pero tiene que llamar manualmente esas funciones, también puede usar boost::intrusive_ptr y proporcionar las definiciones adecuadas para sus funciones add_ref y release. intrusive_ptr los encontrará y los llamará. Ellos son responsables de incrementar el conteo de referencia y disminuirlo, liberando el recurso cuando sea necesario:

 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); } 

Entonces puedes simplemente crear objetos a partir de punteros crudos de tipo foo* . intrusive_ptr llamará a sus funciones cuando se copie / destruya:

 intrusive_ptr 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); 

Para los datos de estilo C, hazlo como @Doug. T sugirió.

Para su clase, ¿por qué no hacer la limpieza en un destructor? Incluso si esto incluye deleteMe () en el destructor.