web-dev-qa-db-fra.com

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-t-il 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;
}
64
Julien Vaslet

Le action déclaré dans la classe dérivée masque le action déclaré dans la classe de base. Si vous utilisez action sur un objet Son, le compilateur recherchera dans les méthodes déclarées dans Son, en trouvera une appelée action et l'utilisera. Il ne poursuivra pas la recherche dans les méthodes de la classe de base, car il a déjà trouvé un nom correspondant.

Ensuite, cette méthode ne correspond pas aux paramètres de l'appel et vous obtenez une erreur.

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

55
sth

Étonnamment, c'est un 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 dérivée "méthode masque la classe de base".

Voir FAQ C++

16
Amnon

Une note de prudence: La nécessité d'utiliser un "using" dans cette situation est un indicateur rouge que votre code peut être source de confusion pour les autres développeurs (après tout, il a confondu 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;
6
Dale Wilson

Si dans une classe dérivée, une fonction surchargée est redéfinie, alors toute la fonction surchargée de la classe de base est masquée. Une façon d'inclure les deux fonctionnalités est d'éviter la surcharge de fonctions dans les classes. ou Vous pouvez utiliser le mot clé using, tel qu'il est utilisé.

5
Bhupesh Pant