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 :

[d�butant] probleme avec une classe arbre


Sujet :

C++

  1. #1
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    2
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 2
    Par d�faut [d�butant] probleme avec une classe arbre
    Salut, je voudrais creer une classe arbre, ou les noeuds ont au maximum n fils.
    J'ai fait un petit truc, j'aimerais savoir s'il n'y a pas des erreurs grossieres (au niveau du style), mais surtout j'ai un probleme quand j'affiche un arbre : il ne va qu'a un rang plus loin... enfin il affiche le noeud courant et ses fils seulement, pas les petits fils.

    Voila le .h :
    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
     
    class Arbre
    {
     public:
      Arbre(){};
      ~Arbre();
      void init(int valeur, int profondeur);
      void Arbre::affiche();
      void Arbre::ajouteFils(Arbre fils);
     
     private:
      Arbre *fils;
      int val;
      int arite;
      int profondeur; //racine a pour profondeur 0
    };
    Et le .cpp :
    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
     
    void Arbre::init(int val, int profondeur)
    {
      Arbre *liste_de_fils=new Arbre[8];
      if(!liste_de_fils)
        exit(0);
      this->fils=liste_de_fils;
      this->val=val;
      this->arite=0;
      this->profondeur=profondeur;
    }
     
    Arbre::~Arbre()
    {
      if (fils!=NULL)
        for (int i=0;i<arite;i++)
          (fils[i]).~Arbre();
    }
     
    void Arbre::ajouteFils(Arbre fils)
    {
      this->fils[arite]=fils;
      arite++;
    }
     
    void Arbre::affiche()
    {
      cout << val << "(";
      if (fils!=NULL)
        for (int i=0;i<arite;i++)
          (fils[i]).affiche();
      cout << ")";
    }
    Vous l'aurez compris je debute, mais je n'ai pas reussi a trouver beaucoup d'info sur les arbres NON binaires

  2. #2
    Membre �clair�
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Par d�faut
    D�j�, les destructeurs, il faut TOUJOURS qu'ils soient virtuels

  3. #3
    Membre chevronn� Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    D�tails du profil
    Informations personnelles :
    �ge : 41
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Par d�faut
    Si tu veux faire un arbre, alors chaque �l�ment de ton arbre doit stocker une liste d'autre �l�ments :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class CElement
    {
        public :
            CElement(void);
     
        protected :
            std::list<CElement> ElementList;
            int Value;
    };
    Tu n'a pas besoin de stocker dans chaque element sa profondeur, ni sont rang.
    Avec cette architecture on a :
    Un element � la base, il stocke une liste d'�l�ment, qui eux aussi stocke des listes d'�l�ments... Pour n'avoir que n �l�ment maxi dans chaque branche alors lors de l'introduction, regarde si dans ta liste tu as d�j� n �l�ments.

  4. #4
    Membre chevronn� Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    D�tails du profil
    Informations personnelles :
    �ge : 41
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Par d�faut
    Voila une class �l�ment plus compl�te :

    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
    // Dans le H
    #include <list>
    class CElement
    {
        public :
            explicit CElement(int Value);
            virtual ~CElement(void);
     
            virtual void AddElement(const CElement& ElementToAdd);
     
        protected :
            std::list<CElement> ElementList;
            int Value;
    };
     
    // Dans le CPP
    CElement::CElement(int Value)
    {
            this->Value = Value;
    }
     
    CElement::~CElement(void) {}
     
    void CElement::AddElement(const CElement& ElementToAdd)
    {
            this->ElementList.push_front(ElementToAdd);
    }
    A toi de coder les accesseurs

  5. #5
    Membre �m�rite Avatar de MatRem
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    750
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 750
    Par d�faut
    D�j�, les destructeurs, il faut TOUJOURS qu'ils soient virtuels
    L� je dirais �a se discute ...
    Si c'�tait le cas, il n'y aurais pas de mot clef virtual et les destructeurs serait toujours virtuel.

    C'est sur que �a peut �tre une bonne habitude, mais ce n'est obligatoire que quand on utilise le polymorphisme, et que les classes d�riv�es ont besoin que leur destructeur soit appell�e.

    Pour ce qui est de la structure de ton code:
    - tu peux peut peu �tre utiliser le constructeur � la place de la fonction init, cela d�pendra de la fa�on dont tu instancie les variables du type Arbre.
    - Comme �a �t� dit il est int�ressant d'utiliser les conteneurs de la biblioth�que standart (comme vector).

    Si tu veux nous faire voir ton main �a peut aider pour voir pourquoi les petis fils ne sont pas affich�s.

  6. #6
    Membre �clair�
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Par d�faut
    Citation Envoy� par MatRem
    L� je dirais �a se discute ...
    Si c'�tait le cas, il n'y aurais pas de mot clef virtual et les destructeurs serait toujours virtuel.

    C'est sur que �a peut �tre une bonne habitude, mais ce n'est obligatoire que quand on utilise le polymorphisme, et que les classes d�riv�es ont besoin que leur destructeur soit appell�e.

    Pour ce qui est de la structure de ton code:
    - tu peux peut peu �tre utiliser le constructeur � la place de la fonction init, cela d�pendra de la fa�on dont tu instancie les variables du type Arbre.
    - Comme �a �t� dit il est int�ressant d'utiliser les conteneurs de la biblioth�que standart (comme vector).

    Si tu veux nous faire voir ton main �a peut aider pour voir pourquoi les petis fils ne sont pas affich�s.
    Je suis pas tout � fait d'accord pour le destructeur.
    Il ne doit pas �tre virtual si on n'utilise pas le polymorphisme et uniquement si on ne l'utilise pas.
    Par exemple si B d�rive de A, qu'on a une collection de A et que l'on d�truit ces objets, le destructeur de B ne sera pas appel� avec un compilo codewarrior car il n'a pas la vtable.
    Et en utilisant gcc sous Mac, si on a toujours B qui d�rive de A et un destructeur non virtual de A ou/et B, et qu'on fait :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
    B* b = new b();
    ...
    ~b(); // Appel implicite
    Ca crache au niveau du destructeur car il ne trouve pas le destructeur parent.
    Dans le cadre de Visual, c'est sur que c'est inutile de d�clarer les destructeurs virtuels gr�ce � la vtable mais si le code doit �tre port�, mieux vaut pr�ciser virtual, �a ne mange pas d epain.
    Mais je veux bien un exemple o� un destructeur ne DOIT PAS �tre virtuel.

  7. #7
    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
    Citation Envoy� par ep31
    Je suis pas tout � fait d'accord pour le destructeur.
    Il ne doit pas �tre virtual si on n'utilise pas le polymorphisme et uniquement si on ne l'utilise pas.
    Par exemple si B d�rive de A, qu'on a une collection de A et que l'on d�truit ces objets, le destructeur de B ne sera pas appel� avec un compilo codewarrior car il n'a pas la vtable.
    Et en utilisant gcc sous Mac, si on a toujours B qui d�rive de A et un destructeur non virtual de A ou/et B, et qu'on fait :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
    B* b = new b();
    ...
    ~b(); // Appel implicite
    Euh... C'est pas plut�t un appel explicite, �a ?
    Dans le cadre de Visual, c'est sur que c'est inutile de d�clarer les destructeurs virtuels gr�ce � la vtable mais si le code doit �tre port�, mieux vaut pr�ciser virtual, �a ne mange pas d epain.
    Mais je veux bien un exemple o� un destructeur ne DOIT PAS �tre virtuel.
    ???
    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.

  8. #8
    Membre �m�rite Avatar de MatRem
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    750
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 750
    Par d�faut
    Par exemple si B d�rive de A, qu'on a une collection de A et que l'on d�truit ces objets, le destructeur de B ne sera pas appel�.
    Normal, je vois pas le probl�me...


    Au niveau de ton exemple je trouve �a bizzare. Je savais pas que le c++ d�finissait l'utilisation du mot clef virtual pour appeller le destructeur de la classe parent ??? (sous gcc c'est automatique)

    N'est ce pas un bug de ton compilateur codewarrior (que je ne connais pas d'ailleurs) ?


    Je vois pas d'exemple concret pour un destructeur non virtuel, mais il doit bien y avoir des cas de polymorphisme ou on ne veut pas que le destructeur de la classe d�riv�e soit appell�... non?

  9. #9
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    2
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 2
    Par d�faut
    En tous cas merci pour votre reponse rapide, je n'avais pas pens� a utiliser les listes en effet. C'est plus simple et c'est ce que je vais faire.

    Par contre je ne comprend toujours pas pourquoi ma fonction afficher ne marche pas...
    Dans le main j'ai mis ca :
    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
    Arbre a;
    a.init(12,0);
    Arbre b;
    b.init(8,1);
    Arbre c;
    c.init(7,2);
    Arbre d;
    d.init(5,3);
     
    a.ajouteFils(b);
    b.ajouteFils(c);
    c.ajouteFils(d);
    a.affiche();
    cout << endl;
    b.affiche();
    cout << endl;
    Et ca me renvoie ca :

    (sans seg fault)

  10. #10
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Citation Envoy� par ep31
    D�j�, les destructeurs, il faut TOUJOURS qu'ils soient virtuels
    Non! En sch�matisant, seulement s'il a une s�mantique d'entit� et que le polymorphisme se tapera probablement (ou s�rement) l'inscruste. Dans le cas d'une s�mantique de valeur, cela enduit en erreur quant � ce que l'on peut v�ritablement faire de l'objet.
    Les destructeurs non publics n'ont pas besoin d'�tre virtuels non plus -- � part peut-�tre des prot�g�s pour des objets polymorphes g�r�s par une factory amie.

    Sinon, pour en revenir � la question de l'OP:
    - toujours s�parer les donn�es de l'IHM. i.e., la pr�sence d'une fonction membre affiche() est rarement recommandable (/jamais ?).

    - Je pr�f�re les d�sign o� les r�les sont bien �tablis => arbre, noeud, feuille

    - s/exit()/throw

    - s/fils+arit�/vector de fils ; cela simplifira le code et corrigera le possible buffer overflow de ajouteFils()

    - ne jamais appeller le destructeur explicitement (il y a quelques tr�s rares cas o� c'est autoris� (limite n�cessaire en fait), mais on en reparlera quand tu ne seras plus un d�butant)

    - Je n'aime pas les fonctions init(). Les constructeurs sont tes amis.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  11. #11
    Membre �m�rite Avatar de MatRem
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    750
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 750
    Par d�faut
    Tu utilises la solution avec les r�f�rences maintenant?
    Postes ton code complet plut�t .

    SI c'est le cas tu dois stocker des r�f�rences vers les objets:
    std::list<CElement &> ElementList;

    et non reinstancier de nouveau �l�ment:
    std::list<CElement> ElementList;

  12. #12
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Citation Envoy� par MatRem
    SI c'est le cas tu dois stocker des r�f�rences vers les objets:
    std::list<CElement &> ElementList;
    ???
    Ceci n'est pas possible. Une r�f�rence est un alias. Ce n'est pas une variable qui puisse �tre stock�e comme les autres.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  13. #13
    Membre �m�rite Avatar de MatRem
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    750
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 750
    Par d�faut
    Ha tient c'est bizarre j'ai toujours cru que c'�tait possible mais je n'ai jamais du le faire...
    Moi qui croyais bien connaitre le c++, me voil� bien surpris.. on en apprends tout les jours

    Pour me faire pardonner des b�tises que j'ai dit , voil� une solution qui fonctionne (en stockant des pointeurs):
    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
    include <cstdlib>
    #include <vector>
    #include <string>
    #include <iostream>
    #include <sstream>
     
    using namespace std;
     
     
    class Arbre{
            public:
                    Arbre(int);
                    void addChild(Arbre & a);
                    string toString();
            private:
                    int value;
                    vector<Arbre *> children;
    };
     
    Arbre::Arbre(int value){
            this->value = value;
    }
    void Arbre::addChild(Arbre & child){
            children.push_back(&child);
    }
    string Arbre::toString(){
            vector<Arbre *>::iterator it;
            ostringstream flux;
     
            flux<<"(["<<value<<"]";
            for(it=children.begin(); it!=children.end(); it++){
                    flux<<(*it)->toString();
            }
            flux<<")";
     
            return flux.str();
    }
     
    int main(){
            Arbre a(1);
            Arbre b(2);
            Arbre c(3);
            Arbre d(4);
            a.addChild(b);
            a.addChild(c);
            b.addChild(d);
     
            cout<<a.toString()<<endl;
     
            return EXIT_SUCCESS;
    }

  14. #14
    R�dacteur

    Avatar de Matthieu Brucher
    Profil pro
    D�veloppeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France, Pyr�n�es Atlantiques (Aquitaine)

    Informations professionnelles :
    Activit� : D�veloppeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par d�faut
    Si tu veux faire encore mieux, passe par des pointeurs intelligents, �a te permettra de ne pas avoir de fuite m�moire, m�me en utilisant des pointeurs - pb que tu risques d'avoir quand tes Arbre() sortiront du scope lorsque le programme sera plus cons�quent -

  15. #15
    Membre �m�rite Avatar de MatRem
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    750
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 750
    Par d�faut
    Si les arbres sortent du scope (ils ne sont plus d�finis), c'est pas vraiment des fuites m�moire que l'on va avoir, mais plut�t des pointeurs NULL, non?

    Ou alors j'ai pas bien compris ce que tu veux dire...

  16. #16
    R�dacteur

    Avatar de Matthieu Brucher
    Profil pro
    D�veloppeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France, Pyr�n�es Atlantiques (Aquitaine)

    Informations professionnelles :
    Activit� : D�veloppeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par d�faut
    Tu auras des pointeurs qui pointent sur du vide, donc le mieux est d'utiliser de l'allocation dynamique, et avec des SP, la gestion est plus simple - pub inside -

  17. #17
    Membre �m�rite Avatar de MatRem
    Profil pro
    Inscrit en
    D�cembre 2002
    Messages
    750
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2002
    Messages : 750
    Par d�faut
    Oki on est d'accord ,

    par contre �a risque de compliquer un peu l'exemple.

  18. #18
    R�dacteur

    Avatar de Matthieu Brucher
    Profil pro
    D�veloppeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    D�tails du profil
    Informations personnelles :
    �ge : 43
    Localisation : France, Pyr�n�es Atlantiques (Aquitaine)

    Informations professionnelles :
    Activit� : D�veloppeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par d�faut
    C'est vrai

Discussions similaires

  1. probleme avec une class
    Par Asmod_D dans le forum C++
    R�ponses: 7
    Dernier message: 15/06/2010, 23h54
  2. Probleme avec une class qui traite la date
    Par tarikmahf dans le forum Collection et Stream
    R�ponses: 3
    Dernier message: 10/11/2008, 22h12
  3. Probleme avec une classe d'association
    Par bassim dans le forum UML
    R�ponses: 7
    Dernier message: 18/04/2007, 14h42
  4. [vb6] D�butant , probleme avec une Grid
    Par axe84 dans le forum VB 6 et ant�rieur
    R�ponses: 5
    Dernier message: 13/06/2006, 10h01
  5. Probleme avec une class template
    Par lenectar dans le forum Langage
    R�ponses: 2
    Dernier message: 01/03/2006, 10h49

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