41 votes

faire en sorte que le shared_ptr n'utilise pas delete

Dans mon code, je voudrais que boost::shared_ptr n'appelle pas delete mais appelle ptr->deleteMe() à la place.

J'ai également quelques fonctions de style C qui renvoient un ptr. Puis-je faire en sorte qu'elles appellent lib_freeXYZ(ptr) ; au lieu d'essayer de les supprimer ?

56voto

Greg Domjan Points 5953

Ou pourquoi ne pas utiliser le stl pour fournir le foncteur d'enveloppe - description de Doug T. mais sans l'appelant personnalisé.

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

37voto

Doug T. Points 33360

Vous pouvez donner au modèle shared_ptr une fonction de suppression personnalisée qui a la signature suivante

  void Deleter( T* ptr);

pour un boost::shared_ptr

Donc, pour le suppresseur, vous devez faire

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

puis dans le corps du suppresseur :

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

Pour votre cas spécifique où vous avez besoin de quelque chose de simple (comme ptr->deleteMe) voir la solution de Greg, c'est très bien.

10voto

Doug T. a bien répondu à votre question. Je vais vous parler de intrusive_ptr. Peut-être que vous pouvez l'utiliser dans votre projet aussi.

Si vous avez une bibliothèque C qui a déjà un comptage de référence, mais que vous devez appeler manuellement ces fonctions, vous pouvez utiliser boost::intrusive_ptr aussi, et fournir des définitions appropriées pour ses fonctions add_ref et release. intrusive_ptr les trouvera et les appellera. Elles sont responsables d'incrémenter le nombre de références et de le décrémenter, en libérant la ressource si nécessaire :

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

Ensuite, vous pouvez simplement créer des objets à partir de pointeurs bruts de type foo* . intrusif_ptr appellera vos fonctions quand il sera copié/détruit :

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

1voto

Kris Kumler Points 4122

Pour les données de style C, faites comme @Doug. T a suggéré.

Pour votre classe, pourquoi ne pas faire le nettoyage dans un destructeur ? Même si cela consiste à inclure deleteMe() dans le destructeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X