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 :

surcharge de l'opérateur de comparaison et polymorphisme


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Décembre 2004
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 25
    Points : 13
    Points
    13
    Par défaut surcharge de l'opérateur de comparaison et polymorphisme
    Bonjour,

    Voilà ça devait arriver, j'ai un nouveau problème et comme la dernière fois c'est ici qu'on m'a sorti de la galère (notamment loulou24), je suis de retour.

    J'écris un code (c'est un devoir de fac) qui permet de tirer et d'afficher un certain nombre de cartes dans un jeu de tarot qui comprend 3 catégories de cartes appelées 'oudlers', 'atouts' et 'cartesimple'.
    Il y a une classe abstraite "carte" et 3 les autres qui dérivent de celle-ci
    Le code fonctionne bien avec une fonction virtuelle hasard() pour tirer une carte et afficher() pour l'afficher.
    La où ça s'est compliqué c'est quand on nous demande de ne pas tirer 2 fois la même carte.
    Je voulais comparer 2 cartes de n'importe laquelle des 3 catégories :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(d.jeu[i] == d.jeu[j])
    où jeu[] est un tableau statique d'objets 'cartes' et d une instance de l'objet 'donne' qui comprend justement le membre 'jeu'
    J'ai donc codé une surcharge de l'opérateur ==, dans la classe mère on a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual bool operator == (carte&) = 0;
    et dans les classe filles, par exemple dans la classe "cartesimple" ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    bool carteSimple::operator == (carte& c) {
    carteSimple* b = dynamic_cast<carteSimple*>(&c);
    if(b -> valeur == valeur) 
       return(true);
    else
       return(false);
    delete b;
    }
    L'opérateur dynamic_cast me permet bien d'accéder à la valeur de la carte, par polymorphisme : j'ai vérifié que b->valeur fournissait la bonne valeur. Mais apparemment, b->valeur et valeur sont toujours égaux. Alors qu'en invoquant 'valeur', je croyais m'adresser à l'instance courante et non pas à la carte passée en paramètre ???

    Est-ce que quelqu'un voit où peut se situer le problème ?

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Salut

    Premièrement si dans ton tableau tu stockes des objets et non des pointeurs, tu peux dire adieu au polymorphisme car tu perds le type dynamique de tes objets. Mais j'imagine que ce n'est pas le cas, car la classe Carte de base est abstraite (ça ne compilerait pas) ?

    Ensuite qu'est-ce qui te dit que tu vas toujours comparer 2 cartes du même type (ie. que le dynamic_cast va réussir) ?

    Enfin remarque stupide : les données nécessaires à la comparaison ne peuvent pas être stockées au niveau de la classe mère :

    (et c'est quoi ce delete b à la fin de ton opérateur de comparaison ?? dynamic_cast ne duplique pas ton objet !!)

  3. #3
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Hiérarchies polymorphiques et sémantique de valeur se marient mal. Je crois qu'un extrait de la FAQ C++ lite, à ce sujet, a été incorporée à la FAQ developpez.

    (sémantique de valeur = copiabilité et comparaison) (note au passage, tu ne parles pas de l'opérateur d'affectation, mais de celui de comparaison)

    Perso j'interdirais comparaison et affectation/recopie, et je me débrouillerais pour n'instancier chaque carte qu'une seule fois.
    S'assurer de tirer à chaque fois une carte différente s'obtient avec un std::random_shuffle, ou n'importe quel tirage aléatoire dans une collection qui ne cesse de diminuer au fur et à mesure que les cartes sont distribuées.

    Pas besoin de tester si une carte a déjà été tirée, ce n'est pas très efficace -- en plus de pousser vers des problèmes de design.



    Maintenant une façon simple de résoudre ton égalité : à priori chaque carte dispose d'un nom/ID. Cette propriété est commune à toutes les spécialisations de cartes. Du coup, tu pourrais réaliser la comparaison avec un simple:
    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
    struct carte
    {
        type_id id() const; //!< à implémenter !
        bool operator==(carte const & rhs) const
        { return id() == rhs.id(); }
     
        reste de l'interface publique
    private:
        carte(carte const &); //!< copie interdite et non implémentée (ieni)
        carte & operator=(carte const &); //!< affectation ieni
     
        divers trucs virtuels purs
     
        eventuels attributs communs
    };
    EDIT: j'y pense pour le problème final, on doit pouvoir faire un truc clean avec un std::max_element pour déterminer qui ramasse. Et je ne vois pas trop l'intérêt (hors exercice poussé) d'une hiérarchie qui introduit probablement un besoin de double-dispatch.
    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...

  4. #4
    Membre à l'essai
    Inscrit en
    Décembre 2004
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 25
    Points : 13
    Points
    13
    Par défaut
    Merci pour vos réponses

    Bon c'est pour la fac, alors j'essaye de faire ça avec les outils qu'on nous conseillent, même si apparemment ce n'est pas la meilleure solution.

    le tableau stocke des objets :
    et le polymorphisme fonctionne apparemment
    Stocker les données dans la classe mère faciliterait les choses, mais comme il faut mettre en oeuvre le polymorphisme au niveau des valeurs ...
    Si le dynamic_cast échoue il retourne 0, ce qui ne devrait pas être génant.
    le code de la surchage de l'opérateur de flux d'entrée qui après la déclaration :
    et l'instructionpermet de tirer au hasard un jeu de cartes :
    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
    istream& operator >> (istream& f, donne& d) {
    for(int i = 0; i<d.taille_jeu; i++) {
          delete d.jeu[i];
       }
    d.taille_courante = 0;
    int nombre;
    char r;
    cout << "\nNombre de cartes a tirer : ";
    f >> nombre;
    d.taille_jeu = nombre;
    for(int i = 0; i< d.taille_jeu; i++) {
       cout << "\nbout ou atout ou carte simple (1/2/3) : ";
       f >> r;
       switch(r) {
          case '1' : d.jeu[i] = new bout();break;
          case '2' : d.jeu[i] = new atout();break;
          case '3' : d.jeu[i] = new carteSimple();break;
          }
          d.jeu[i] -> hasard();
          for(int j=0; j<d.taille_courante; j++) {
             if(d.jeu[i] == d.jeu[j]) {
                d.jeu[i] -> hasard();
                j=0;
                }
             }
          d.taille_courante++;
       }
    return(f);
    }
    Une des méthodes hasard() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void bout::hasard() {
    int val = random(nb_carteBout);
    vb = valeur_bout(val);
    }
    elle utilise les énumérations :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    enum valeur_bout {un,vingt_et_un,excuse};
    Je ne comprend pas que dans la surcharge de mon opérateur de comparaison (j'ai corrigé l'erreur dans le titre du sujet), vb ne me donne pas la valeur du membre de l'instance courante. car quand j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(d.jeu[i] == d.jeu[j])
    Il y a bien l'instance qui est passée en paramètre à la méthode de surcharge de l'opérateur == , soit (carte& c) plus une instance courante ??
    je sais pas, le membre à gauche de l'opérateur d'égalité est-il l'instance courante ou finalement est-il la carte qui est passée en paramètre ??

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(d.jeu[i] == d.jeu[j])
    Sauf erreur de frappe de ta part en postant, tu compares 2 pointeurs là.

  6. #6
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Toute carte a un identifiant unique "roi de trêfle", "deux de carreau", "20 d'atout", ...
    Même si la donnée n'est pas stockée au niveau de la classe parente, tu vas devoir disposer d'un accesseur vers cette propriété.

    Compare les résultats de cet accesseur. Utiliser dynamic_cast est ici une erreur de conception.

    Ton opérateur >> est trop compliqué et mélange des choses différentes.
    Décompose successivement ton problème en problèmes plus simples.

    La libération est notament le boulot d'un destructeur.
    Mais plus simplement, on pourrait avoir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    std::istream operator>>(std::istream & is, donne & d)
    {
        donne nouvelle_donne;
        for (int i=0 ; i!=NB ; ++i) {
            carte * c = 0;
            do {
                c = lit_carte(is);
                if (!is) return is;
            } while (nouvelle_donne . carte_presente(c) );
            nouvelle_donne . ajoute(c);
        }
        d.swap(nouvelle_donne);
    }
    Et de là, tu n'as plus qu'à écrire les sous fonctions qui sont fort simples.

    Mais cette façon de mélanger n'est absolument pas réaliste -- j'aimerai pouvoir demander les bouts...

    Je verrais plutôt:
    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
    enum_couleur { carreau, trefle, coeur, pique, C_END };
    jeu::jeu() 
    {
        int a = 0;
        cartes_[a++] = new escuse();
        cartes_[a++] = new petit();
        for ( ; a != 21 ; ++a)
            cartes_[a] = new atout(a);
        cartes_[a++] = new vingtetun();
        for (enum_couleur c=carreau ; c!= C_END ; ++c)
            for (enum_cartes v=as ; v!=v_END ; ++v)
            cartes_[a++] = new carte_normale(c, v);
    }
     
    // et si tu ne veux pas utiliser le shuffle_random:
    jeu jeu::jeu_melange() const
    {
        std::vector<carte*> v0(cartes_+0, cartes_+NB);
        std::vector<carte*> v2(NB);
        for (int i=0 ; i!=NB ; ++i) {
            std::vector<carte*>::iterator it = 
                v0.begin() + random_sur_(v0.size());
            v2[i] = *it;
            v0.erase(it); // ou remove ?
        }
        return jeu(v2);
    }
     
    jeu::jeu(std::vector<carte*> const & v)
    {
        std::copy(v.begin(), v.end(), cartes_);
    }


    Quant à "lhs == rhs", c'est équivalent à "lhs.operator==(rhs)"
    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...

  7. #7
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Citation Envoyé par Loulou24
    Premièrement si dans ton tableau tu stockes des objets et non des pointeurs, tu peux dire adieu au polymorphisme car tu perds le type dynamique de tes objets. Mais j'imagine que ce n'est pas le cas, car la classe Carte de base est abstraite (ça ne compilerait pas) ?
    Effectivement, à moins de caster l'objet (ce qui transforme sa VTable), on ne peut pas faire un push_back() des héritiers dans un vector<ClassMere>...
    (Fonction vector<T>::push_back(T) [T=ClasseFille] non trouvée)

    Ce qui signifie que que ClasseFille* 'isA" ClasseMere*, mais NOT(ClasseFille isA ClasseMere) (si je me fais comprendre...)

    C'est finalement sémantiquement absurde (je ne m'étais jamais fait la reflexion, qui a dit "narrow-minded"...).
    Il doit y avoir une raison technique, mais pour l'instant je ne vois pas... Il est un peu tard, l'illumination viendra peut-être demain, la nuit porte conseil...)
    Gaïa n'est pas une marchandise.

  8. #8
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Ce qui se passe lors du passage par valeur d'un objet polymorphique, c'est que seule sa partie correspondant à la classe mère sera copiée (c'est ce qu'on appelle le slicing), et tu te retrouves donc avec un objet qui a perdu toutes les données concernant son type dérivé. Evidemment ça ne marche pas si la classe mère est abstraite.

  9. #9
    Membre à l'essai
    Inscrit en
    Décembre 2004
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 25
    Points : 13
    Points
    13
    Par défaut
    La libération est notament le boulot d'un destructeur
    Merci j'ai supprimé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(int i = 0; i<d.taille_jeu; i++) {
    delete d.jeu[i]
    dans le code de méthode de surcharge du flux >>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(d.jeu[i] == d.jeu[j])
    Sauf erreur de frappe de ta part en postant, tu compares 2 pointeurs là.
    T'étais prof dans un autre vie ou quoi ??
    oui ! le programme ne marchait pas uniquement pour cette raison
    j'ai remplacé par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(*d.jeu[i] == *d.jeu[j])
    Et o miracle ... !

    C'est un peu comme pour mon dernier problème : je sais que ce qu'est qu'un pointeur mais j'ai tendance à oublier les implications que ça représente. Je trouve ça bizarre de ne pas avoir été averti par une erreur de compilation ...

    Encore une fois, merci !

  10. #10
    Membre à l'essai
    Inscrit en
    Décembre 2004
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 25
    Points : 13
    Points
    13
    Par défaut
    Juste pour ajouter une précision

    quand loulou24 a écrit :
    Ensuite qu'est-ce qui te dit que tu vas toujours comparer 2 cartes du même type (ie. que le dynamic_cast va réussir) ?
    Il avait raison !

    et à l'exécution, je parvenais bien à éviter les doublons de carte mais dès que j'essayais de tirer 2 cartes différentes, j'avais une erreur Windows.

    J'ai donc ajouté une fonction virtuelle que j'ai codé dans chaque classe dérivée de la classe carte, par ex pour la classe atout :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int atout::type_classe(){
    return(1);
    }
    et avant de lancer la comparaison dans la méthode de surcharge du flux d'entrée, je fais un test pour voir si les deux cartes sont de même type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(d.jeu[i]->type_classe() == d.jeu[j]->type_classe())
    donc le problème est cette fois bien résolu

  11. #11
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    C'est sâââle ! Mais vraiment.
    Une fonction id() est ce qu'il te faudrait si tu persistes à vouloir comparer des cartes. (Pour le reste j'ai déjà signalé que cette approche de pioche est inefficiente)
    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...

  12. #12
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Citation Envoyé par Luc Hermitte
    Une fonction id() est ce qu'il te faudrait si tu persistes à vouloir comparer des cartes. (Pour le reste j'ai déjà signalé que cette approche de pioche est inefficiente)
    [/quote]
    Pourtoant n'est-ce pas une sorte de RTTI utilisateur qu'il implémente en l'occurence ?
    OK un VERITABLE id serait plus approprié qu'un "booléen"...

    Citation Envoyé par Luc Hermitte
    C'est sâââle !
    J'espère juste que tu ne parle pas du RTTI utilisateur, sinon, moi, je vais te parler de mon avertion pour les <dynamic|staic_cast>... Que je n'utilise JAMAIS.
    Question de design...
    Gaïa n'est pas une marchandise.

  13. #13
    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 : 49
    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
    Je n'aime pas trop le RTTI non plus, mais s'il en faut un, je préfère celui du langage qui marche que celui utilisateur qui a une bonne probalité de ne pas marcher.

    En affet, si C dérive de B qui dérive de A, que tu as un A* qui pointe sur un C, et que tu veux savoir s'il pointe sur un B, la bonne réponse est oui, mais la réponse de la plupart des RTTI utilisateurs que j'ai pu voir est non.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  14. #14
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    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 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Hello.

    Je ne parle pas de faire une fonction id() utilisateur qui remplacerait le typeid(), mais d'une fonction, de type accesseur à spécialiser, qui renvoit une propriété qui se doit d'être discriminante pour toutes les cartes : son nom. (Roi de carreau, deux d'atout, ...)

    "Mon" "sâââle" s'applique au dynamic_cast qui est utilisé dans son implémentation actuelle du op==().
    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...

  15. #15
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Citation Envoyé par JolyLoic
    Je n'aime pas trop le RTTI non plus, mais s'il en faut un, je préfère celui du langage qui marche que celui utilisateur qui a une bonne probalité de ne pas marcher.

    En affet, si C dérive de B qui dérive de A, que tu as un A* qui pointe sur un C, et que tu veux savoir s'il pointe sur un B, la bonne réponse est oui, mais la réponse de la plupart des RTTI utilisateurs que j'ai pu voir est non.
    Effectivement, dans ce cas il ne suffit pas de renvoyer une chaine de caractère...
    Néanmoins le seul type de RTTI (utilsateur) que j'ai jamais utilisé était celui d'AReVi (Atelier Réalité Virtuelle, ici) qui le fait très bien (il faut néanmoins connaitre l'arbre d'héritage, mais ça le fait... Bon en l'occurence cette bib's fait tout, multi-agent, garbage collector, etc... c'est presque une extention du C++)...
    Gaïa n'est pas une marchandise.

  16. #16
    Membre à l'essai
    Inscrit en
    Décembre 2004
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 25
    Points : 13
    Points
    13
    Par défaut
    Salut à tous,

    Je voulais vous faire part d'un retour concernant le problème évoqué, à savoir comment tester le type de carte :

    Il y a effectivement beaucoup plus simple que de coder une fonction virtuelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int atout::type_classe(){ 
    return(1); 
    }
    pour ne pas faire planter la surcharge de l'opérateur d'égalité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    carteSimple* b = dynamic_cast<carteSimple*>(&c); 
    if(b -> valeur == valeur) //risque de plantage
       return(true); 
    else 
       return(false); 
    delete b; 
    }
    En fait, il suffisait de tester si l'affectation avait réussi :
    Parcequ'en cas d'échec, c'est que les 2 cartes ne sont pas du même type !

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

Discussions similaires

  1. Surcharge de l'opérateur new
    Par :Bronsky: dans le forum C++
    Réponses: 17
    Dernier message: 27/10/2010, 21h33
  2. Portabilitée : Surcharge opérateur de comparaison
    Par Dimitri_87 dans le forum C++
    Réponses: 11
    Dernier message: 15/12/2006, 16h14
  3. Réponses: 6
    Dernier message: 12/07/2006, 15h34
  4. Pb avec l'opérateur de comparaison IN
    Par petitnuage dans le forum Requêtes
    Réponses: 2
    Dernier message: 06/06/2006, 16h13
  5. implémentation des opérateurs de comparaison
    Par niko8181 dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 28/04/2005, 11h58

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