78 votes

Pourquoi devrais-je utiliser le mot-clé "using" pour accéder à ma méthode de classe de base?

J'ai écrit le code ci-dessous afin d'expliquer mon problème. Si je commente la ligne 11 (avec le mot clé "using"), le compilateur ne compile pas le fichier et affiche cette erreur: invalid conversion from 'char' to 'const char*' . Il semble ne pas voir la méthode void action(char) de la classe Parent dans la classe Son .

Pourquoi le compilateur se comporte de cette façon? Ou ai-je fait quelque chose de mal?

 class Parent
{
    public:
        virtual void action( const char how ){ this->action( &how ); }
        virtual void action( const char * how ) = 0;
};

class Son : public Parent
{
    public:
        using Parent::action; // Why should i write this line?
        void action( const char * how ){ printf( "Action: %c\n", *how ); }
};

int main( int argc, char** argv )
{
    Son s = Son();
    s.action( 'a' );
    return 0;
}
 

66voto

sth Points 91594

L' action déclarée dans la classe dérivée cache l' action déclarée dans la classe de base. Si vous utilisez action sur Son objet le compilateur va chercher dans les méthodes déclarées dans l' Son, trouver un appelé action, et l'utiliser. Il n'ira pas à la recherche dans la classe de base des méthodes, depuis qu'il a déjà trouvé un nom correspondant.

Alors que la méthode ne correspond pas aux paramètres de l'appel et vous obtiendrez une erreur.

Voir aussi le C++ FAQ Lite pour plus d'explications sur ce sujet.

20voto

Amnon Points 4864

Étonnamment, c'est le comportement standard. Si une classe dérivée déclare une méthode portant le même nom qu'une méthode définie par la classe de base, la méthode de la classe dérivée masque celle de la classe de base.

Voir http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9

6voto

Dale Wilson Points 3089

Attention: le besoin d'utiliser un "using" dans cette situation est un signal d'alarme que votre code peut être déroutant pour les autres développeurs (après tout, cela a dérouté le compilateur!). Il est probable que vous deviez renommer l'une des deux méthodes pour que la distinction soit claire pour les autres programmeurs.

Une possibilité:

 void action( const char how )
{ 
  takeAction( &how ); 
}
void action( const char * how )
{
  takeAction(how);
}
virtual void takeAction(const char * how) = 0;
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X