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 :

Question à propos de virtual method et de Vector


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre prolifique
    Avatar de Ryu2000
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2008
    Messages
    10 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2008
    Messages : 10 243
    Par défaut Question à propos de virtual method et de Vector
    Bonjour.

    Pour faire simple j'ai une classe mère appelé Mere et des classes filles appelées Fille1, Fille2 et Fille3.

    Je veux que Mere force ses filles à implémenter methode1(void) et methode2(void).

    Donc dans Mere.h j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public :
         virtual methode1(void) = 0;
         virtual methode2(void) = 0;
    A un moment je veux un vector remplit de Fille1, Fille2, Fille3.
    Et un truc très important aussi, je ne veux faire aucun free et aucune allocation de mémoire.

    A la base j'avais pas les Filles et je faisais avec un Vector de Mere du coup je pouvais faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    vector <Mere> listeMere;
    ...
    Mere m1(5.0,1.3);
    listeMere.push_back(m1);
    Mais comme là j'ai des méthodes virtual, je suis obligé d'utilisé des pointeurs.
    J'ai vu que ça parlait d'un shared_ptr.

    Du coup j'ai fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    static vector <shared_ptr<Mere>> listeMere;
    ...
    listeMere.push_back(shared_ptr<Mere> m1(new Fille1(i, 5)));
    Bon le truc chiant c'est que j'ai du changer des . en ->.
    Mais sinon c'est correct ?

    Dans le principe, c'est propre ?
    C'est performant ?

    Parce que là je peux faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listeMere[0]->methode1();
    Et si listeMere[0] est une Fille1 ça appelle bien Fille1.methode1(); donc ça fonctionne.

    Niveau mémoire j'ai quelque chose à gérer ?

    Ou alors existe il une autre solution pour avoir un vecor de mere est pouvoir appeler methode1 et methode2 dans n'importe quelle fille ?
    Parce qu'en Java j'aurais dis que Mere est une interface et les Filles implements Mere ou un truc comme ça, il me semble que c'est ça parce qu'en disant que t'implements tu dois forcer à implémenter les méthodes de l'interface mère.

    Apparemment shared_ptr ça ralentit pas mal.
    Si vraiment faut j'utilise les pointeurs tant pis, je ferais des free...

    Si vous avez des indications à me donner merci de me les indiquer.
    Au revoir.

    Edit :
    Finalement c'est aussi lent avec des pointeurs normaux.

    Edit :
    J'ai juste à appelé delete() et c'est bon ?
    Je fais comment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    delete listeMere[i];
    listeMere.erase(listeMere.begin()+i);
    ?

    Sinon c'est utile les shared_ptr ?

  2. #2
    Membre émérite
    Homme Profil pro
    R&D imagerie 3D / prog embarquée
    Inscrit en
    Mars 2007
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : R&D imagerie 3D / prog embarquée
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2007
    Messages : 419
    Par défaut
    Salut,

    Citation Envoyé par thierrybenji Voir le message
    Dans le principe, c'est propre ?
    à mon avis, oui c'est propre.

    Citation Envoyé par thierrybenji Voir le message
    C'est performant ?
    Ca dépend toujours de ton contexte, mais à mon avis on peut mieux faire. Tout d'abord parce qu'à chaque fois que tu sort un objet de ton vecteur, tu devra copier ton shared_ptr, donc incrémenter ton compteur de référence. Puis quand ces shared_ptr seront détruit, il faudra décrémenter ton compteur de ref, vérifier s'il tombe à 0 et éventuellement détruire (ce qui n'arrive pas avant que ton vecteur soit vidé ou détruit)
    Si ton vecteur est, par exemple, encapsulé dans une classe et représente une composition (et non une agrégation), j'y mettrais plutôt des pointer et je gèrerais les désallocations manuellement. Ca évite de prendre le overhead de la gestion des shared_ptr.

    Citation Envoyé par thierrybenji Voir le message
    Niveau mémoire j'ai quelque chose à gérer ?
    Non, le shared_ptr gére pour toi.

    Citation Envoyé par thierrybenji Voir le message
    Ou alors existe il une autre solution pour avoir un vecor de Mere est pouvoir appeler methode1 et methode2 dans n'importe quelle fille ?
    Si tu veux dire en mettant directement des Mere dans le vecteur, je ne pense pas que ça soit possible. Comme tu le sais surement déjà, pour utiliser le polymorphisme en C++ tu dois travailler soit avec des pointers, soit avec des références.
    Ce problème vient entre autre du fais que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sizeof(Mere) != sizeof(Fille1)
    Donc, si tu allou sur la stack une Mere, tu n'aura surement pas la place d'y mettre une fille. Le problème s'étend facilement au vecteur. Si ce dernier contient des Mere, alors la taille de chaque cellule de ce dernier sera de sizeof(Mere). Impossible d'y coller une Fille1. Par contre, une référence ou un pointer fait toujours la même taille.
    Une des conséquences de tout ça, c'est qu'il n'y aura aucun lookup dans la table des fonctions virtuelles si tu appelle une fonction sur autre chose qu'un pointer ou une réf.

  3. #3
    Membre prolifique
    Avatar de Ryu2000
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2008
    Messages
    10 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2008
    Messages : 10 243
    Par défaut
    Merci beaucoup pour vos réponses.

    Donc shared_ptr gère la mémoire mais est un peu moins performant.

    Et si je veux utiliser des pointeurs normaux, lorsque j'enlève un objet du vector je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    vector <Mere*> listeMere;
    ...
    listeMere.push_back(new Fille1());
    ...
    delete listeMere[i];
    listeMere.erase(listeMere.begin()+i);
    C'est le destructeur de la classe mère qui est appelé mais je pense que ça fonctionne comme ça.
    Là niveau mémoire j'ai bien libéré la mémoire de l'objet stocké dans le vector ?
    Il ni a rien a écrire dans le destructeur ?

    Ça semble beaucoup plus pratique que les malloc et les free.

  4. #4
    Membre émérite
    Homme Profil pro
    R&D imagerie 3D / prog embarquée
    Inscrit en
    Mars 2007
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : R&D imagerie 3D / prog embarquée
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2007
    Messages : 419
    Par défaut
    Citation Envoyé par thierrybenji Voir le message
    Là niveau mémoire j'ai bien libéré la mémoire de l'objet stocké dans le vector ?
    Il ni a rien a écrire dans le destructeur ?
    Exact, sauf que vector n'est en fait qu'un tableau dynamique, donc si tu fais beaucoup de "erase" autre que sur le "end" de ton vector, tu as mal choisi ton container, car pour retirer un élément, tu dois déplacer tous ceux qui suivent.
    Le problème ne se pose plus si tu détruit tout d'un coup. En premier tu itére sur ton vecteur et tu delete chaque objet, puis tu appelle "clear" sur ton vector.

    Pour ce qui est du destructeur, tu appelle bien celui de Mere, mais il devrait être déclaré virtuel, ce qui appellera celui des différentes FilleX selon le type de l'objet pointé.

  5. #5
    Membre prolifique
    Avatar de Ryu2000
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2008
    Messages
    10 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2008
    Messages : 10 243
    Par défaut
    Merci.

    Ah oui, il faut déclarer le destructeur comme virtual, purée j'ai pas refais de C++ depuis des années j'ai perdu le truc.
    Mais j'imagine que ça ne change pas grand chose, puisqu'il ni a rien dans le destructeur et que les classes filles n'ont pas plus de variable que la classe mère, en fait elles implémentent juste deux méthodes.

    Quel Container serait mieux adapté ?

    En fait je remplit une liste au début et petit à petit je la vide.
    Je supprime les objets de la liste totalement dans le désordre.
    C'est plutôt aléatoire.

    Je réalise un Space Invaders en utilisant OpenGL :
    [ame="http://www.youtube.com/watch?v=ewbshlA_Ke4"]http://www.youtube.com/watch?v=ewbshlA_Ke4[/ame]

    Les monstres, les murs, les tirs tout est stocké dans des vector.

  6. #6
    Membre émérite
    Homme Profil pro
    R&D imagerie 3D / prog embarquée
    Inscrit en
    Mars 2007
    Messages
    419
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : R&D imagerie 3D / prog embarquée
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2007
    Messages : 419
    Par défaut
    Citation Envoyé par thierrybenji Voir le message
    purée j'ai pas refais de C++ depuis des années j'ai perdu le truc.
    Héhé, je comprend tout à fait

    Citation Envoyé par thierrybenji Voir le message
    Quel Container serait mieux adapté ?
    Bien comme ça c'est difficile à dire. Je ne connais pas toutes tes contraintes. Je ne sais même pas ce que ton vecteur doit contenir. La suppression d'un élément aléatoire ne doit pas être la seule opération que tu fais sur ton container. Donc, choisir uniquement sur ce critère n'est vraiment pas optimal.
    Après, pour l'insertion séquentielle, tu es toujours à O(1) pour les containers non-ordonnés et O(log(N)) pour les ordonnés.
    Par contre, ce lien compare les différentes opérations des containers de la STL. Ca devrait t'aider à faire ton choix.

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

Discussions similaires

  1. question à propos d'un std::vector encapsuler
    Par Date90 dans le forum C++
    Réponses: 2
    Dernier message: 05/04/2009, 15h20
  2. Question à propos des niveaux de transaction
    Par davy.g dans le forum Oracle
    Réponses: 3
    Dernier message: 18/01/2005, 15h31
  3. Petite question à propos du redbook...
    Par Michaël dans le forum OpenGL
    Réponses: 3
    Dernier message: 04/11/2004, 12h54
  4. Petite question à propos d'une requete
    Par ViBy dans le forum Langage SQL
    Réponses: 4
    Dernier message: 15/09/2004, 12h21
  5. Une question à propos des thread
    Par tscoops dans le forum C++Builder
    Réponses: 4
    Dernier message: 07/11/2003, 14h03

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