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

Langage C++ Discussion :

Destruction d'objet problématique


Sujet :

Langage C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 37
    Points : 18
    Points
    18
    Par défaut Destruction d'objet problématique
    Bonjour,
    Je ne vois pas comment me sortir d'un problème de pointeur pouvant pointer sur un objet détruit, dans le cas suivant:

    Le contexte:
    J'ai des objets de classe A qui peuvent avoir un parent, de même classe, et qui de plus peuvent émettre un event:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class A {
        A * parent = 0;
        B * listener = 0;
        void notifyEvent();
        void addListener(B * b);
    }
    Quand l'event est émis, la méthode B::receiveEvent() est appelée.
    J'ai besoin d'une méthode permettant d'émettre des events à la chaine, à partir d'un objet A, et en remontant ses parents:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void alert(A * a){
        while( a ){
            a->notifyEvent(); // (1)
            a = a->parent;    // (2)
        }
    }
    Le problème:
    J'aimerais donner la possibilité, à l'intérieur de B::receiveEvent(), de détruire (delete) l'objet A qui a émis l'évènement.
    Mais si je fais cela, la ligne (2) peut provoquer une erreur, puisque l'objet pointé par a sera détruit au moment de son exécution.

    Idées de solution, mais bof bof:
    Je pourrais mémoriser avec un autre pointeur le parent de a, avant la ligne (1).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void alert(A * a){
        while( a ){
            A * parent = a->parent;
            a->notifyEvent(); // (1)
            a = parent;    // (2)
        }
    }
    Ce qui résoudrait le problème, mais j'aimerais, dans B::receiveEvent(), pouvoir également détruire le parent de a, où tout ancêtre plus éloigné.

    Je pourrais introduire une methode A::destroy() qui marquerait un objet comme étant à détruire, et traiter les destructions une fois sorti de la boucle de alert().
    Mais ne serait-ce pas introduire une spécificité d'utilisation de ma classe, source d'erreur en cas d'oubli, l'utilisateur devant penser à appeler destroy() plutôt que delete?



    Est-ce que quelqu'un verrait une bonne solution ?
    Merci.

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    La méthode qui consiste à détruire plus tard est à mon avis la plus simple d'utilisation. Mais pas forcement la plus simple à implémenter.
    Certaines bibliothèques le font (ex: Qt avec la fonction QObject::deleteLater).

    Une autre solution peu être de fournir un signal lors de la destruction de l'objet et informer ceux qui y sont attachés.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void alert(A * a)
        struct WhenDestroy {
           A * a;
           void operator()(A * a) {
             a = a->parent;
             if (a) {
               a->connect(destroy_event, Signal(std::ref(*this))); 
             }
          }
        } when_destroy{a};
        while( a ){
            a->connect(destroy_event, Signal(std::ref(when_destroy)));
            a->notifyEvent(); // (1)
            if (a != when_destroy.a) {
                a = when_destroy.a;
            }
            else {
              a = a->parent;    // (2)
            }
        }
    }

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 37
    Points : 18
    Points
    18
    Par défaut
    Merci de ta réponse !
    Je ne comprends pas le code de ta deuxième solution, mais ça m'a donné des idées, et de fil en aiguille j'en suis arrivé à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class A {
        A * parent = 0;
        B * listener = 0;
        ~A(){
            onADestruction( this );
        }
        void notifyEvent();
        void addListener(B * b);
    }
     
    A * currentNotifier = 0;
    void alert(A * a){
        currentNotifier = a;
        while( currentNotifier ){
            currentNotifier->notifyEvent();
            if( currentNotifier ) currentNotifier = currentNotifier->parent;
            else currentNotifier = 0;
        }
    }
     
    void onADestruction( A * a ){
        if( currentNotifier == a ) currentNotifier = 0;
    }
    Quand un objet A est détruit, il le signale par le biais de la méthode onADestruction(), qui fait attention à la gestion du pointeur de la boucle de notification dans alert().

    Mes premiers tests sont concluants. Merci

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

Discussions similaires

  1. [VB.NET 2.0] Destruction d'objet
    Par Torkan dans le forum Windows Forms
    Réponses: 3
    Dernier message: 01/06/2006, 02h02
  2. destruction d'objet
    Par goth dans le forum Langage
    Réponses: 8
    Dernier message: 19/03/2006, 15h52
  3. Destruction d'objet (.free) >> EAccessViolation
    Par monstroplante dans le forum Langage
    Réponses: 7
    Dernier message: 08/11/2005, 20h19
  4. destruction d'objets dans un vecteur
    Par titouille dans le forum C++
    Réponses: 12
    Dernier message: 28/07/2005, 19h20
  5. [débutante][Concept] Destruction d'objet, mode d'emploi?
    Par skea dans le forum Général Java
    Réponses: 4
    Dernier message: 12/06/2004, 21h48

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