IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

delete this; ??


Sujet :

C++

  1. #1
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut delete this; ??
    Bonjour à tous,

    voilà, je viens de tomber, au détour d'un morecau de code sombre et sinueux, sur une méthode du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void UneClasse::ReleaseRef()
    {
    	m_nbRef--;
    	if (m_nbRef <= 0)
    		delete this;
    }
    Veuillez pardonner mon manque de clairvoyance, mais je ne comprends pas comment le "delete this;" peut marcher! En effet, comment est-il possible de détruire la classe alors qu'on est dedans (dans le sens où on est dans une méthode qui appartient à cette classe)?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  2. #2
    Membre régulier Avatar de Blowih
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 122
    Points : 115
    Points
    115
    Par défaut
    Bonjour,
    je me trompe peu etre,
    la fonction est appelée sur un instance de la classe, donc a ce moment elle existe.
    le delete detruit cette instance, a partir du delete l'instance n'xsite plus, et donc on ne peux plus faire d'appel sur cette instance.

    ça ressemble a un systeme de pointeur "intelligent" qui efface l'instance d'une classe des quele n'est plus utilisé

    en esperant que ça reponde a ta question

    Ben

  3. #3
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut Re: delete this; ??
    Citation Envoyé par r0d
    Veuillez pardonner mon manque de clairvoyance, mais je ne comprends pas comment le "delete this;" peut marcher! En effet, comment est-il possible de détruire la classe alors qu'on est dedans (dans le sens où on est dans une méthode qui appartient à cette classe)?
    Tant qu'apres le delete this tu ne fais pas appel aux membres, il n'y a pourtant pas de problemes.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    D'ailleurs, en C++, on peut appeler une fonction non-virtuelle sur un objet NULL...
    (Simplement, dans la fonction, il ne faut pas faire appel aux membres... Ce n'est pas pour autant l'équivalent d'une fonction static, parce qu'on peut tester si this est NULL ou non)

    J'ai vu ceci par exemple dans MFC:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    HWND CWnd::GetSafeHwnd()
    {
    	return ((this==NULL) ? NULL : m_hWnd);
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Médinoc
    D'ailleurs, en C++, on peut appeler une fonction non-virtuelle sur un objet NULL...
    Non, on ne peut pas. C'est peut-etre autorise comme extension par certains compilateurs, ca fonctionne vraissemblablement plus ou moins par chance avec beaucoup -- du moins en attendant que l'optimiseur y mette son nez -- mais ce n'est pas du code conforme.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Je ne vois pas pourquoi ça fonctionne "par chance" : Une fonction non-virtuelle ne dépend pas de l'objet lui-même pour être appelée... (Contrairement au java où toutes les fonctions sont virtuelles)

    Mais j'avoue que j'ignorais que ce n'était pas conforme au standard.


    PAS-Edit: Ah, je viens de voir où peut être le problème: L'héritage!
    Là, surtout en cas d'héritage multiple, this ne sera pas NULL, mais une valeur légèrement supérieure à zéro! (D'ailleurs, c'est également possible avec les histoires de vtable, je pense)
    En effet, là, ça peut avoir des effets de bord dangereux, dus à la non-nullité de this...
    Ah là là, l'héritage multiple est cause de bien des soucis... Pas étonnant qu'il ait été abandonné avec dotNet...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    mat.M
    Invité(e)
    Par défaut
    Médinoc je vais passer pour un pinailleur mais le terme "fonction" n'existe pas en Java non ?
    On parle de méthodes d'une classe et non de fonctions .
    Par contre fonctions en C oui parce qu'elles ne sont rattachées à rien..
    Bon c'était juste pour pinailler inutilement

  8. #8
    mat.M
    Invité(e)
    Par défaut
    Citation Envoyé par Blowih
    Bonjour,
    je me trompe peu etre,
    la fonction est appelée sur un instance de la classe, donc a ce moment elle existe.
    le delete detruit cette instance, a partir du delete l'instance n'xsite plus, et donc on ne peux plus faire d'appel sur cette instance.

    ça ressemble a un systeme de pointeur "intelligent" qui efface l'instance d'une classe des quele n'est plus utilisé

    en esperant que ça reponde a ta question

    Ben
    Tout à fait d'accord bonne réponse.
    En fait de pointeur "intelligent" ReleaseRef c'est une terminologie Microsoft ( technologie COM ).
    M$ avec ses objets COM a voulu un peu , avouons le , refaire la POO du C++ à sa sauce.
    Plutot que d'utiliser constructeurs et destructeurs, AddRef , DeleteRef , QueryInterface et autres sont appelés pour instancier des objets COM.

    Mais Microsoft a été contraint de se livrer à cette "cuisine" parce que les ojbets COM peuvent être appelés par Delphi , VB bref tout langage qui supporte COM, Active X , OLE.
    Ce qui permet d'expliquer peut-être delete this

  9. #9
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    En bon débutant que je suis, je ne comprends pas l'interret d'un delete this.

    Ca veut alors dire que si on appelle une telle instruction, l'objet est obligatoirement alloué dynamiquement

    quelque part c'est du suicide on laisse à l'objet la decision de dire si il a été alloué dynamiquement ou non....

    Enfin ca n'est que mon sentiment de humble débutant que je suis.

  10. #10
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Médinoc
    Je ne vois pas pourquoi ça fonctionne "par chance" : Une fonction non-virtuelle ne dépend pas de l'objet lui-même pour être appelée... (Contrairement au java où toutes les fonctions sont virtuelles)
    Comme tu l'as vu, il y a le probleme de l'heritage multiple. Il y a aussi le probleme des optimiseurs; a partir du moment ou ils sont concus pour supposer quelque chose, bien malins ceux qui peuvent prevoir ce qu'ils vont en deduire.

    Je n'ai plus l'exemple precis en tete, mais j'ai eu une fois l'impression qu'il se servait d'une supposition de ce genre pour reecrire le passe... Son raisonnement etait quelque chose comme: si une telle expression est valide, c'est que telle variable contient un nombre compris entre tant et tant a ce moment la, donc aussi a ce moment anterieur aussi; cette autre expression est donc constante et toujours fausse et donc cette branche du if n'est jamais executee, supprimons tout ce code inutile... Pas de chance un il avait un bug qui faisait que l'expression initiale n'etait pas utilisee de maniere conforme mais j'ai eu du mal a le trouver parce que justement la branche du if anterieur a l'expression n'etait pas executee. C'est ce genre de chance dont je parlais... Ce genre de raisonnement permettrait a un optimiseur de virer le if avant l'appel a fonction_membre ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (ptr == NULL) {
       std::cerr << "Attention pointeur NULL" << std::endl;
    }
     
    ptr->fonction_membre();
    et tu n'aurais jamais le message "Attention pointeur NULL".
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  11. #11
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par giova_fr
    Ca veut alors dire que si on appelle une telle instruction, l'objet est obligatoirement alloué dynamiquement
    Il y a souvent des classes dont on sait qu'elles ne seront instanciees que dynamiquement.

    delete this arrive souvent aussi dans des gestions d'evenements (une instance de fenetre recoit la notification que l'utilisateur vient de cliquer sur le bouton qui permet de la fermer et l'instance se detruit donc, un observeur recoit notification que l'objet qu'il observe est detruit et se detruit donc aussi,...).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  12. #12
    Membre averti
    Avatar de bigquick
    Profil pro
    Inscrit en
    Août 2002
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 356
    Points : 353
    Points
    353
    Par défaut
    giova_fr a écrit:
    Ca veut alors dire que si on appelle une telle instruction, l'objet est obligatoirement alloué dynamiquement Shocked

    Il y a souvent des classes dont on sait qu'elles ne seront instanciees que dynamiquement.
    D'ailleurs, pour empecher une instanciation sur la pile, tu peux rendre le destructeur privé. Un code du type "Noeud n;" refusera de compiler.

    J'ai vu ça utilisé dans la bibliothèque OpenSceneGraph, pour inciter l'utilisateur à utiliser les pointeurs intelligents (vu qu'on est obligé de faire "new Noeud" et que ces Noeuds sont référencés à de nombreux endroits dans le graphe, autant gérer leurs durées de vie avec des pointeurs intélligents ).
    And still we will be here, standing like statues ...

  13. #13
    Membre habitué
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Points : 164
    Points
    164
    Par défaut
    Que se passera t-il si l'objet n'est pas alloué dynamiquement? et qu'on rencontre le delete this ?
    ( car j'ai utilisé ca quelquepart ... bon, si mes souvenir sont bon, les objet sont forcément alloué dynamiquement, mais, si ce genre de code produit des erreur, je ferai bien d'aller m'assurer qu'ils sont bien tous alloué comme il le faut ^^ )
    merci .

  14. #14
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Clad3
    Que se passera t-il si l'objet n'est pas alloué dynamiquement? et qu'on rencontre le delete this ?
    Et bien ça passe. Je ne comprends pas trop pourquoi, mais je viens de tester:
    suivant le modèle du premier post, j'ai fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UneClasse maClasse(<parametres>);
    Ensuite, j'ai mis un point d'arrêt sur le ReleaseRef, et j'ai lancé l'exécution de l'appli. Et bien tout s'est bien passé: la création de l'objet ainsi que sa destruction.
    :
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  15. #15
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Clad3
    Que se passera t-il si l'objet n'est pas alloué dynamiquement? et qu'on rencontre le delete this ?
    N'importe quoi... un crash immédiat, rien de notable, une erreur subtile par la suite...
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  16. #16
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    à tous

    j'avais laissé ce sujet un peu au cas où quelqu'un n'ait eu envie de rajouter quelque chose. Il semble que je puisse le clore maintenant.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/04/2009, 09h38
  2. opération 'delete this'
    Par coyotte507 dans le forum C++
    Réponses: 12
    Dernier message: 01/07/2007, 15h39
  3. [DOM] delete this possible?
    Par Rashomonfr dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 31/10/2006, 17h46
  4. probleme de delete this
    Par venomelektro dans le forum C++
    Réponses: 8
    Dernier message: 03/07/2006, 09h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo