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 :

Classe qui s'appelle elle-même dans sa définition ?


Sujet :

Langage C++

  1. #1
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut Classe qui s'appelle elle-même dans sa définition ?
    Bonjour à tous.

    Je suis en train de coder un ensemble de classes pour faire une arborescence (BGL ne me permettant pas bien de faire ce que je souhaite faire). Et ce qui serait plus simple pour moi c'est que chaque objet est un pointeur vers son père et un pointeur vers un tableau de fils dans la structure en arborescence.

    Bref, j'aurai besoin d'un truc de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class MaClasse
    {
        private:
            MaClasse* pere;
            MaClasse* fils[8];
    };
    Question : est-ce que ce genre de chose fonctionne bien et même dans le cas où cela fonctionne est-ce que c'est considéré comme "propre" ?

    Merci

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 617
    Points
    15 617
    Par défaut
    pour l´utilisation du nom de la classe, pas de problème (class MaClass est une définition de MaClass donc elle peut être utilisée ensuite)
    Par contre, c´est un choix d´utiliser des pointeurs nus et de pas utiliser un vector ?

  3. #3
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    Pour la question sur les vector : pure raison de perfs. J'ai noté des différences de perfs entre les vector et les tableaux C (j'ai posté une question là dessus récemment), et comme c'est un code destiné à tourner sur supercalculateurs, je veux éviter de perdre du temps avec des vectors alors que des tableaux C sont aussi simples à utiliser dans ce cas précis (il y aura surement des vectors dans d'autre parties de mon code mais pas là). (pour préciser l'arborescence comptera en général plus de 100 milliards d'éléments donc il faut que le truc soit plutôt bien conçu).

  4. #4
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    turlututu, std::vector est tout a fait utilsiable dans un contexte HPC, du moment ou on l'utilise avec un allocateur correct et qu'on compile en -NDEBUG. Utilsier des pointeurs nus c'ets chercher le bugs car on a eu la flemme d'ecrire un operateru d'affectation.

  5. #5
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    Re.

    Comme vous avez beaucoup plus d'expérience que moi sur ces questions, quelle serait la bonne méthode à employer ? (pour les pointeurs j'ai des habitudes venant du C).

    Sachant que ma problématique est la suivante :
    - je veux du code sûr
    - je travaillerai environ avec 5 millions de MaClasse par CPU et la taille prise par chaque objet en mémoire est critique
    - j'ai prévu pour chaque objet MaClasse 7 datamembers : 1 entier 64 bit + 2 entiers 8 bit + 3 pointeurs vers MaClasse (racine, pere, fils) + 1 pointeur vers AutreClasse
    - Le pointeur vers racine : soit est NULL, soit pointe vers 1 racine
    - Le pointeur vers pere pointe : soit est NULL, soit pointe vers 1 pere
    - Le pointeur vers fils : soit est NULL, soit pointe vers un tableau de 8 fils

    Quel est le meilleur moyen de faire cela de façon sûre sans augmenter la place que j'ai prévu en mémoire ?

    Merci beaucoup

    EDIT : + je peux utiliser les nouveautés de C++2011

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Joel F Voir le message
    turlututu, std::vector est tout a fait utilsiable dans un contexte HPC, du moment ou on l'utilise avec un allocateur correct et qu'on compile en -NDEBUG. Utilsier des pointeurs nus c'ets chercher le bugs car on a eu la flemme d'ecrire un operateru d'affectation.
    Comme en l’occurrence, le nombre de fils a l'air fixe, un std::array doit probablement être plus efficace qu'un std::vector, non ?

    A moins que cette valeur de 8 soit un maximum, que pour la quasi totalité des nœuds il n'y ait que 2 fils, et qu'on gagne plein de mémoire en utilisant un vector ?

  7. #7
    Membre habitué
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Points : 176
    Points
    176
    Par défaut
    En gros je commence un module de maillage adaptatif pour un futur code N-body (avec relativité générale). En N dimensions (3 en général), si on atteint 2^N particules (8 en général) dans une cellule alors on ajoute un niveau de raffinement et on génère 2^N fils. Donc en gros soit il n'y a pas de fils, soit il y en a 8....

    Et juste une question : dans mon std::array je mettrai quoi : des pointeurs ou directement les objets ?

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par Joel F Voir le message
    turlututu, std::vector est tout a fait utilsiable dans un contexte HPC, du moment ou on l'utilise avec un allocateur correct et qu'on compile en -NDEBUG. Utilsier des pointeurs nus c'ets chercher le bugs car on a eu la flemme d'ecrire un operateru d'affectation.
    D'ailleurs, si quelqu'un connaît un site qui aborde ces problématique de performances liées au stockage, je suis preneur.

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,
    Citation Envoyé par Kaluza Voir le message
    Et juste une question : dans mon std::array je mettrai quoi : des pointeurs ou directement les objets ?
    Le problème, c'est qu'il faut, quoi qu'il en soit, être en mesure de déterminer la taille exacte utilisée en mémoire par ta structure!!!

    Toute structure de taille non dynamique t'obligera à utiliser des pointeurs car, si la taille que prend un pointeur en mémoire est connue, il est difficile de rompre la récursion lorsqu'il s'agit de calculer la taille prise en mémoire par une structure qui contient une (collection) d'objets du meme type.

    De plus, le constructeur étant appelé de manière implicite dés qu'un objet doit être créé, si tu travailles sur des objets, tu vas entrer dans une récursion dont il te sera impossible de sortir!

    Tu ne peux donc pas avoir quelque chose du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class MyClass
    {
        public: 
           MyClass():children(8){}
        private:
           std::vector<MyClass> children;
    };
    ou du genre de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class MyClass
    {
        public: 
           MyClass(){}
        private:
           std::array<MyClass,8> children;
    };
    car le constructeur de MyClass sera appelé de manière récursive pour créer les 8 objets servant pour children jusqu'à ce que le système t'envoies paitre (lorsque la pile d'appels explosera )

    Il faut donc, dans le meilleur (ou le pire, je ne sais pas ) des cas, faire en sorte que la création des enfants ne se fasse en tout cas pas dans le constructeur.

    Un code proche de
    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
     
    #include <cassert>
    #include <vector>
    class MyClass
    {
        public:
            MyClass()
            {}
            MyClass const & operator[](size_t index) const
            {
                assert(index < children.size());
                return children[index];
            }
            MyClass & operator[](size_t index)
            {
                assert(index < children.size());
                return children[index];
            }
            void createChildren()
            {
                children = std::vector<MyClass>(8);
            }
            size_t childCount() const{return children.size();}
        private:
            std::vector<MyClass> children;
    };
    int main()
    {
         MyClass tree;
         std::cout<<tree.childCount()<<std::endl;
         /* décommente ceci pour voir l'assertion à l'oeuvre ;) */
         // tree[2].createChildren();
         tree.createChildren();
         std::cout<<tree.childCount()<<std::endl;
         MyClass & subtree=tree[2];
         std::cout<<subtree.childCount()<<std::endl;
         subtree.createChildren();
         std::cout<<subtree.childCount()<<std::endl;
         return 0;
    }
    fonctionnerait par exemple tout à fait correctement, et ferait, si j'ai bien compris, exactement ce que tu souhaites, à savoir t'assurer que, à tout moment, un objet n'aura soit qu'un seul, soit que 8 enfants mais met à mal le principe du RAII (enfin, si on le prend vraiment au pied de la lettre )

    Si tu veux utiliser un tableau C style ou un std::array (voire faire en sorte de créer dés le départ un std::vector avec 8 éléments ) tu devras de toutes manières utiliser des pointeurs pour éviter le problème de l'appel récursif du constructeur (et il te faudra, de toutes manières, une fonction membre permettant de créer les enfants )

  10. #10
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Comme en l’occurrence, le nombre de fils a l'air fixe, un std::array doit probablement être plus efficace qu'un std::vector, non ?

    A moins que cette valeur de 8 soit un maximum, que pour la quasi totalité des nœuds il n'y ait que 2 fils, et qu'on gagne plein de mémoire en utilisant un vector ?
    Evidemment. Je rebondissais juste sur ce bon vieux FUD du vector super-lent

Discussions similaires

  1. Réponses: 11
    Dernier message: 25/07/2012, 18h56
  2. [AC-2002] Chaine qui ne s'équivaut pas à elle-même dans liste déroulante
    Par Nightwing367 dans le forum IHM
    Réponses: 7
    Dernier message: 19/04/2011, 19h14
  3. Réponses: 5
    Dernier message: 28/05/2008, 16h18
  4. class qui en appel une autre qui peux planter !
    Par deadliff dans le forum Langage
    Réponses: 7
    Dernier message: 20/03/2007, 15h40
  5. Une iframe qui se supprime elle-même
    Par jibouze dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 19/12/2005, 10h11

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