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++/CLI Discussion :

Appel r�cursif au destructeur : une horreur ?


Sujet :

C++/CLI

  1. #1
    Membre averti
    Profil pro
    CTO
    Inscrit en
    F�vrier 2009
    Messages
    20
    D�tails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activit� : CTO

    Informations forums :
    Inscription : F�vrier 2009
    Messages : 20
    Par d�faut Appel r�cursif au destructeur : une horreur ?
    Bonjour � tous,

    Dans un but purement d'entrainement, je code une classe pour g�rer une liste chain�e.

    Pour cela j'ai choisi la technique du premier �l�ment bidon (le premier �l�ment n'en est pas un, c'est juste une accroche, cr�� lors de l'appel du constructeur).

    Tout fonctionne pour le moment bien, mais j'aimerais votre avis sur mon destructeur...

    Comme chaque �l�ment ajout� dans la liste est cr�� dynamiquement avec un "new", j'avais besoin de g�rer la lib�ration de la m�moire dans le destructeur.

    Une technique que j'ai trouv� est tout simplement de sauter le premier �l�ment (bidon), puis dans le cas g�n�ral :
    sauvegarder l'�l�ment suivant
    appel� le destructeur dessus si il n'est pas nul

    �a permet de parcourir et de d�truire tous les �l�ments de la liste...

    En ex�cution �a plante pas, en console j'ai une trace de la suppression de tous les �l�ments, bref �a � l'air de marcher.
    Mais j'aimerai votre avis de pro.
    Est-ce inutile, dangereux, idiot ?
    Voici le code :

    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
     
    Noeud::~Noeud()
    {
        Noeud *maillon_suivant = NULL;
        //premier appel du destructeur, depuis la tete de la liste, la valeur de this. On a pas besoin de faire un delete de cet élément, il n'a pas été alloué dynamiquement
        if ( this->est_accroche_liste() ){
            maillon_suivant = this->maillon_suivant;
            maillon_suivant->~Noeud();
        }
        //un appel après, sur un maillon quelquonque qui doit être supprimé
        else{
            cout << "Suppression de l'element "+ this->valeur << endl;
            maillon_suivant = this->maillon_suivant;//on sauve le suivant
     
            //Si le maillon suivant n'est pas à NULL (on n'est pas au bout de la chaine), on appel le destructeur sur le maillon suivant
            if( maillon_suivant != NULL){
                //cout << "Maillon suivant : "+ maillon_suivant->valeur << endl;
                delete maillon_suivant;
            }
        }
    }
    et le code complet de l'impl�mentation de la classe :

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    #include "../include/Noeud.h"
     
    Noeud::Noeud(): valeur("NULL"), maillon_suivant(NULL)
    {
        //cout << "Construction du premier element" << endl;
    }
     
    Noeud::Noeud(string s): valeur(s), maillon_suivant(NULL)
    {
        //cout << "Construction de l\' element :"+s << endl;
    }
     
    Noeud::~Noeud()
    {
        Noeud *maillon_suivant = NULL;
        //premier appel du destructeur, depuis la tete de la liste, la valeur de this. On a pas besoin de faire un delete de cet élément, il n'a pas été alloué dynamiquement
        if ( this->est_accroche_liste() ){
            maillon_suivant = this->maillon_suivant;
            maillon_suivant->~Noeud();
        }
        //un appel après, sur un maillon quelquonque qui doit être supprimé
        else{
            cout << "Suppression de l'element "+ this->valeur << endl;
            maillon_suivant = this->maillon_suivant;//on sauve le suivant
     
            //Si le maillon suivant n'est pas à NULL (on n'est pas au bout de la chaine), on appel le destructeur sur le maillon suivant
            if( maillon_suivant != NULL){
                //cout << "Maillon suivant : "+ maillon_suivant->valeur << endl;
                delete maillon_suivant;
            }
        }
    }
     
    bool Noeud::est_accroche_liste(){
        return valeur == "NULL";
    }
     
    bool Noeud::est_dernier_maillon(){
        return maillon_suivant == NULL;
    }
     
    void Noeud::ajout_au_bout(string valeur_a_ajouter){
        Noeud *noeud_a_ajouter = new Noeud(valeur_a_ajouter);
        Noeud* noeud_actuel = this;
     
        while( noeud_actuel->maillon_suivant != NULL){
            noeud_actuel = noeud_actuel->maillon_suivant;
        }
        noeud_actuel->maillon_suivant = noeud_a_ajouter;
    }
     
    void Noeud::ajout(string valeur_a_ajouter, int indice){
        int indice_depart = 1;
        Noeud *noeud_a_ajouter = new Noeud(valeur_a_ajouter);
        Noeud *noeud_actuel = this;
        Noeud *ancien_noeud_suivant = NULL;
     
        while( noeud_actuel->maillon_suivant != NULL && indice_depart < indice){
            noeud_actuel = noeud_actuel->maillon_suivant;
            indice_depart++;
        }
        //une fois le bon élément atteint, on insère le nouveau après cet élément, puis on le raccroche à la suite de la liste
        ancien_noeud_suivant = noeud_actuel->maillon_suivant;
        noeud_actuel->maillon_suivant = noeud_a_ajouter;
        noeud_a_ajouter->maillon_suivant = ancien_noeud_suivant;
    }
     
    string Noeud::get_valeur_noeud(int indice){
        int indice_actuel = 0;
        Noeud* noeud_actuel = this;
     
        while( noeud_actuel->maillon_suivant != NULL && indice_actuel < indice){
            noeud_actuel = noeud_actuel->maillon_suivant;
            indice_actuel++;
        }
        return noeud_actuel->valeur;
    }
     
    int Noeud::get_taille(){
        int taille = 0;
        Noeud* noeud_actuel = this;
     
        while( noeud_actuel->maillon_suivant != NULL){
            noeud_actuel = noeud_actuel->maillon_suivant;
            taille++;
        }
        return taille;
    }
     
    void Noeud::parcours(){
        Noeud* Noeud_actuel = this;
     
        if( est_accroche_liste()){
            Noeud_actuel = this->maillon_suivant;
        }
     
        while( Noeud_actuel->maillon_suivant != NULL ){
            cout << "Dans while " + Noeud_actuel->valeur << endl;
            Noeud_actuel = Noeud_actuel->maillon_suivant;
        }
        cout << "Dernière valeur : " + Noeud_actuel->valeur << endl;//On n'oublie pas d'afficher la dernière valeur
    }
    D'avance merci

    PS : je sais bien s�r, y'a la STD et tout �a, c'est juste pour m'entrainer et bien comprendre

  2. #2
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    �a me parait dangereux. Tu devrais plut�t cr�er un nouvel objet temporaire vide, et faire un non-throwing swap de leurs contenus. �a �vitera de risquer d'appeler deux fois le destructeur sur les m�mes donn�es.

    Ensuite, j'ai l'impression que ton probl�me c'est de confondre cha�non et liste. Je pense que tu devrais utiliser une classe Liste, qui poss�derait un pointeur vers le Noeud bidon et s'occuperait de la destruction des Noeuds au lieu de faire en sorte que chaque Noeud tente de d�truire le suivant.
    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.

Discussions similaires

  1. R�ponses: 3
    Dernier message: 30/03/2007, 10h38
  2. Appel de fonction d'une DLL en TANSAC SQL
    Par sylvain114d dans le forum MS SQL Server
    R�ponses: 3
    Dernier message: 19/01/2006, 10h21
  3. R�ponses: 15
    Dernier message: 07/07/2005, 11h05
  4. R�ponses: 3
    Dernier message: 23/06/2004, 21h17
  5. Appel de proc�dure dans une page ASP
    Par PrinceMaster77 dans le forum ASP
    R�ponses: 5
    Dernier message: 02/04/2004, 16h59

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