29 votes

Fonction membre du C++ : surcharge et surcharge virtuelle en même temps

Si j'ai un code comme celui-ci :

struct A {
  virtual void f(int) {}
  virtual void f(void*) {}
};

struct B : public A {
  void f(int) {}
};

struct C : public B {
  void f(void*) {}
};

int main() {
  C c;
  c.f(1);

  return 0;
}

J'obtiens une erreur qui me dit que j'essaie de faire une conversion invalide de int à void*. Pourquoi le compilateur ne comprend-il pas qu'il doit appeler B::f, puisque les deux fonctions sont déclarées comme virtuelles ?


Après avoir lu la réponse de Jalf, je l'ai encore réduit. Celle-ci ne fonctionne pas aussi bien. Elle n'est pas très intuitive.

struct A {
  virtual void f(int) {}
};

struct B : public A {
  void f(void*) {}
};

int main() {
  B b;
  b.f(1);

  return 0;
}

43voto

jalf Points 142628

La réponse courte est "parce que c'est ainsi que fonctionne la résolution des surcharges en C++".

Le compilateur recherche les fonctions F à l'intérieur de la classe C et, s'il en trouve, il arrête la recherche et essaie de choisir un candidat parmi ces fonctions. Il ne cherche dans les classes de base que si aucune fonction correspondante n'a été trouvée dans la classe dérivée.

Toutefois, vous pouvez introduire explicitement les fonctions de la classe de base dans l'espace de noms de la classe dérivée :

struct C : public B {
  void f(void*) {}
  using B::f; // Add B's f function to C's namespace, allowing it to participate in overload resolution
};

1voto

fulmicoton Points 5389

J'avais quelques doutes à ce sujet, mais en effet il ne compile pas. Voici une version simplifiée du code qui illustre le même problème.

class A {
  public:
     virtual void f(int) {}
     virtual void f(void*) {}
};

class B : public A {
  public:
     virtual void f(void*) {}
};

int main() {
  B b;
  b.f(1);
  return 0;
}

-1voto

user2432444 Points 1

Vous pouvez aussi faire ceci :

void main()
{
    A *a = new C();
    a->f(1);  //This will call f(int) from B(Polymorphism)
}

-6voto

saravanan Points 1

Je pense tout d'abord que vous n'avez pas compris ce qu'est le mécanisme virtuel ou le polymorhisme. Lorsque le polymorphisme est réalisé uniquement en utilisant des pointeurs d'objets. Je pense que vous êtes novice en C++. Sans l'utilisation de pointeurs d'objets, le polymorphisme et le mot-clé virtuel n'ont aucun sens. Utilisez le pointeur de la classe de base et affectez-lui les objets de la classe dérivée souhaitée. Ensuite, appelez et essayez.

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