web-dev-qa-db-fra.com

problème c ++ avec surcharge de fonction dans une classe héritée

C'est peut-être une question noob, désolé. J'ai récemment rencontré un problème étrange en essayant de jouer avec des trucs de haut niveau en c ++, la surcharge de fonctions et l'héritage.

Je vais montrer un exemple simple, juste pour illustrer le problème;

Il existe deux classes, classA et classB, comme ci-dessous;

class classA{
    public:
        void func(char[]){};    
};

class classB:public classA{ 
    public:
        void func(int){};
};

D'après ce que je sais, classB devrait maintenant posséder deux fonctions func(..), surchargées en raison d'arguments différents.

Mais lorsque vous essayez cela dans la méthode principale;

int main(){
    int a;
    char b[20];
    classB objB;
    objB.func(a);    //this one is fine
    objB.func(b);    //here's the problem!
    return 0;
}

Il donne des erreurs car la méthode void func(char[]){}; qui est dans la super classe, classA, n'est pas visible dans la classe dérivée, classB.

Comment puis-je surmonter cela? n'est-ce pas ainsi que fonctionne la surcharge en c ++? Je suis nouveau en c ++ mais en Java, je sais que je peux utiliser quelque chose comme ça.

Bien que j'aie déjà trouvé ce fil qui pose des questions sur des problèmes similaires, je pense que les deux cas sont différents.

45
Sumudu

Tout ce dont vous avez besoin est un using:

class classB:public classA{ 
    public:
        using classA::func;
        void func(int){};
};

Il ne recherche pas la classe de base pour func car il en a déjà trouvé une dans la classe dérivée. L'instruction using place l'autre surcharge dans la même portée afin qu'elle puisse participer à la résolution de la surcharge.

57
chris

C'est bien expliqué par exemple dans les réponses à cette question:

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

En bref, le compilateur arrêtera de rechercher les méthodes correspondantes des classes parentes, lorsqu'il trouvera le nom de la méthode correspondante dans la classe actuelle, même lorsque cette méthode n'est pas compatible. Je suppose que cela permet à certaines conversions de types automatiques de fonctionner de manière plus logique, sans avoir à remplacer autant de méthodes de classe parent.

11
hyde

Si vous remplacez une variante d'une fonction dans la classe dérivée, vous devez remplacer toutes les variantes. Vous pouvez soit utiliser ce que JLledo a suggéré, soit écrire la variante de la fonction dans la classe dérivée qui appelle simplement la fonction de même signature de la classe de base.

class classA{
    public:
        void func(char[]){};    
};

class classB:public classA{ 
    public:
        void func(int){};
        void func(char[]){};
};

void classB:func(char[] ch)
{
    classA::func(ch);
}
3
Girish Matti