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 :

Opérateur, héritage et liaison dynamique


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 26
    Par défaut Opérateur, héritage et liaison dynamique
    Hello

    J'ai actuellement un soucis avec gcc. Je suis pas un pro C++, je viens plutot du monde JAVA, alors pardonnez moi si je divague.

    Bref, je m'explique.

    J'ai 1 classe mère, mettons M, et deux classes qui héritent en public de M, mettons Ma et Mb.

    M défini un operateur == avec en paramètre M.

    Je voudrais pouvoir surcharger cet opérateur dans Ma, de tel façon que si le second oprande est de type Ma on utilise l'opérateur == de Ma, et celui de M sinon.

    En gros pour résumer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    M m1;
    Ma ma1,ma2;
    Mb mb1;
     
    ma1 == ma2; // utilise l'opérateur Ma::operator==
    ma1 == m1;   // utilise l'opérateur M::operator==
    ma1 == mb1;   // utilise l'opérateur M::operator== (car Mb est un sous type de M).
    La défnition des classes ci dessus expliquée serait la suivante :
    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
     
    class M {
        public:
        M() {}
        ;
        virtual ~M(){};
        virtual bool operator==(M m) {
            std::cout <<" M::operator=="<<std::endl;
            return true;
        };
    };
     
    class Ma : public M{
        public:
        Ma() {}
        ;
        virtual ~Ma(){};
     
        virtual bool operator==(Ma m) {
            std::cout <<" Ma::operator=="<<std::endl;
            return true;
        };
    };
     
    class Mb : public M{
        public:
        Mb() {}
        ;
     
    };
    Tout cela est plutot simple.
    Sauf que si je fais le test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Ma ma1;
    Mb mb1;
     
    ma1==mb1
    je me retrouve avec une erreur de compil :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    src/test/testMisc.cpp:101: error: no match for 'operator==' in 'ma1 == mb1'
    src/test/testMisc.cpp:40: note: candidates are: virtual bool Ma::operator==(Ma)
    Il semblerait donc que la liaison dynamique ne marche pas en C++?

    Encore plus étonnant :
    Je fais un copier coller de la définiton de l'opérateur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        virtual bool operator==(M m) {
            std::cout <<" M::operator=="<<std::endl;
            return true;
        };
    de la classe M vers la classe Ma (qui défini donc ==(Ma) et ==(M)).
    Et la ca passe...

    J'avoue êrte un peu perdu...

    Quelqu'un pour éclairer ma lanterne?
    D'avance merci.

  2. #2
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Ma::operator== ne supplante pas M::operator== parce qu'il n'a pas la meme signature (compare avec un Ma, pas avec un M). Mais comme il a le meme nom, il le masque. Donc ma1 == mb2 ne trouve pas d'operateur adequat. Quand par apres tu le supplantes, il le trouve bien.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 26
    Par défaut
    Magnifique!

    Grand merci pour ce dépannage express.

    Solution au problème :

    il suffit de préciser dans la classe Ma qu'on "démasque" l'opérateur ==(M) grace au mot clé "using" ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Ma : public M{
        public:
        Ma() {}
        ;
        virtual ~Ma(){};
     
        using M::operator==;
     
        virtual bool operator==(Ma m) {
            std::cout <<" Ma::operator=="<<std::endl;
            return true;
        };
    };
    Encore merci.

  4. #4
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Juste pour préciser, il y a un paquet de point virgule en trop dans ton code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Ma : public M{
        public:
        Ma() {}
        virtual ~Ma(){}
     
        using M::operator==;
     
        virtual bool operator==(Ma m) {
            std::cout <<" Ma::operator=="<<std::endl;
            return true;
        }
    };
    est correct

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Il est facile de s'embrouiller avec les opérateurs et la virtualité, et je ne maitrise pas cela moi-même.
    Pour moi, le mieux est de déléguer, en faisant un opérateur libre, qui appelle des fonctions virtuelles 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
    //Déclarations de classes
    class A
    {
    public:
    	virtual int CompareTo(A const & autre) const = 0;
    };
     
    class Aa
    {
    public:
    	virtual int CompareTo(A const & autre) const;
    private:
    	int x;
    };
     
    class Ab
    {
    public:
    	virtual int CompareTo(A const & autre) const;
    private:
    	short y;
    };
    //Opérateur libre
    bool operator==(A const & lun, A const & lautre);
     
    //Implémentations virtuelles
    int Aa::CompareTo(A const & autre) const
    {
    	Aa const & autreMoi = dynamic_cast< Aa const & >(autre);
     
    	return x - autreMoi.x;
    }
     
    int Ab::CompareTo(A const & autre) const
    {
    	Ab const & autreMoi = dynamic_cast< Ab const & >(autre);
     
    	short diff = y - autreMoi.y;
    	return diff;
    }
     
    //Opérateur libre
    bool operator==(A const & lun, A const & lautre)
    {
    	int res = lun.CompareTo(lautre);
    	assert( lautre.CompareTo(lun) == -res );
    	return (res==0);
    }
    Ça compile, mais je ne l'ai pas testé...

    Edit: Ah, grillé...
    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.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 26
    Par défaut
    @poukill > merci pour la remarque, code nettoyé

    @medioc> je trouve ta solution plus propre et plus lisible, mais c'est pas trop objet comme approche.

  7. #7
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    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 292
    Par défaut
    C'est très java-ien comme problématique.
    En C++, on ne se la pose plus.

    Soit nos objets ont une sémantique de valeur (et sont donc comparables), alors ils n'appartiennent à aucune hiérarchie

    Soit nos objets ont une sémantique d'entité (typique des objets issus de hiérarchies polymorphes), et les comparer n'a aucun sens. On pourra comparer certains de leurs champs, mais c'est tout.
    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...

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

Discussions similaires

  1. Liaison dynamique !
    Par Franck.H dans le forum Linux
    Réponses: 2
    Dernier message: 16/08/2006, 14h25
  2. Liaison dynamique et vitesse des programmes
    Par sebzinzin dans le forum Langage
    Réponses: 2
    Dernier message: 11/04/2006, 09h51
  3. Problème de liaison dynamique...
    Par Franck.H dans le forum Linux
    Réponses: 13
    Dernier message: 24/06/2005, 18h45
  4. [DP][héritage]sous-casting dynamique
    Par Le prophete dans le forum Général Java
    Réponses: 4
    Dernier message: 20/08/2004, 11h56
  5. [xsl]simuler le mecanisme OO de "liaison dynamique"
    Par philemon_siclone dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 19/12/2003, 11h34

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