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 :

Polymorphisme et fonctions virtuelles


Sujet :

C++

  1. #1
    Membre éprouvé Avatar de pcdwarf
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2010
    Messages
    267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 267
    Points : 964
    Points
    964
    Par défaut Polymorphisme et fonctions virtuelles
    Bonjour.

    J'ai eu un bug dans mon code.
    J'ai ramené le problème à cette version simplifiée.

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class A {
        public: void foo(const bool v);
        public: virtual void foo(void)=0;
    };
     
    class B : public A {
        public: void bar();
        public: virtual void foo(void) final ;
    };
     
    void B::bar(){
       foo(true);
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    test.cpp: In member function ‘void B::bar()’:
    test.cpp:12:12: error: no matching function for call to ‘B::foo(bool)12 |    foo(true);
          |            ^
    test.cpp:8:26: note: candidate: ‘virtual void B::foo()8 |     public: virtual void foo(void) final ;
          |                          ^~~
    Je ne comprends pas pourquoi ça ne va pas chercher A::foo(const bool)
    Est-ce une erreur d'écriture ou bien est-ce interdit, et auquel cas, pourquoi ?
    a noter que
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    void B::bar(){
       A::foo(true);
    }
    fonctionne mais je ne pige pas pourquoi je suis obligé de préciser A::

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Tu fais face au masquage de fonction (name hiding).

    Note au passage qu'en C++ il n'est pas nécessaire de mettre public: devant chaque fonction. Tant que tu n'en spécifies pas une nouvelle, la même visibilité reste appliquée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class Foo {
    public:
        void foo(int);    // public
        void foo(char);   // public également
    private:
        void bar(int);    // private
        void bar(char);   // private également
    };

  3. #3
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 648
    Points
    7 648
    Par défaut
    Bonjour,

    Le lien donne la règle et les 2 moyens d'accéder à foo(bool) mais il n'indique pas le pourquoi.

    Pour comprendre le pourquoi, on peut prendre un exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class B : public A {
        public: void  foo( long x ) { std::cout << "foo(long x) => " << x << '\n'; }
    };
     
    class D : public B , public C {
        public: void  foo( char x ) { std::cout << "foo(char x) => " << static_cast<int>(x) << '\n'; }
                void  bar();
    };
     
    void  D::bar() {
       foo( 3 );
    }
    Que va afficher la fonction bar()?
    Comme on a la règle du masquage, aucune ambiguïté, ça affiche "foo(car x) => 3"

    Si on n'avait pas cette règle, tu préfèrerais peut-être avoir "foo(long x) => 3". Es-tu bien sûr que ça ferait cela?
    Une info avant de répondre. Je n'ai pas précisé le code de class A ni de class C.

    Le masquage permet de ne pas se retrouver à appeler une fonction qui pourrait apparaître à l'insu de notre plein grés. Grâce à la règle du masquage, tu n'as qu'à mettre dans class D la séquence using B::foo; et tu garantis qu'il n'y a pas de piège.

  4. #4
    Membre chevronné Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 043
    Points : 2 234
    Points
    2 234
    Par défaut
    Le terme anglais exacte si tu cherches sur internet est "name masking"! Le " Name masking" qui s'applique aux variables s'appelle du "variable shadowing"
    Homer J. Simpson


  5. #5
    Membre éprouvé Avatar de pcdwarf
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2010
    Messages
    267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 267
    Points : 964
    Points
    964
    Par défaut
    Citation Envoyé par Winjerome Voir le message
    Bonsoir,
    Note au passage qu'en C++ il n'est pas nécessaire de mettre public: devant chaque fonction. Tant que tu n'en spécifies pas une nouvelle, la même visibilité reste appliquée :
    Oui je sais mais je voulais réduire le nombre de lignes au maximum. C'est aussi pour ça que j'ai omis les constructeurs/destructeurs. Désolé si j'ai créé de la confusion en faisant ainsi.


    En tout cas merci pour le mot clé "Name masking". Je vais pouvoir me documenter davantage.

    Note : Je comprends bien le problème que peuvent poser le propotions automatiques. Mon intuition était que ce masquage n'avait pas à s'appliquer en l'absence d'ambiguité (En l'occurence sur un nombre de paramètres différents et/ou n'ayant pas de conversion implicite).

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

Discussions similaires

  1. polymorphisme et fonction virtuelle
    Par r0d dans le forum C#
    Réponses: 10
    Dernier message: 04/06/2011, 22h30
  2. Compilation avec des fonctions virtuel pure
    Par vanitom dans le forum C++
    Réponses: 4
    Dernier message: 16/12/2005, 14h37
  3. masquage de fonction virtuelle
    Par julien.sagnard dans le forum C++
    Réponses: 3
    Dernier message: 27/01/2005, 14h00
  4. Réponses: 2
    Dernier message: 07/10/2004, 17h00
  5. fonctions virtuelles
    Par Mau dans le forum Autres éditeurs
    Réponses: 4
    Dernier message: 21/11/2003, 09h53

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