Bonjour,
J’ai un petit problème certainement très basique que je ne comprends pas.
J’ai une interface I1, et une seconde interface I2 qui étend I1. J’ai une class C1 qui implémente I1, et une classe C2 qui étend C1 et qui implémente I2. C’est très très simple:
struct I1 {
virtual void foo () = 0;
};
struct I2: I1 {
virtual void bar () = 0;
};
struct C1: I1 {
void foo () override {
std::cout << "Foo from I1" << std::endl;
}
};
struct C2: C1, I2 {
void bar () override {
std::cout << "Bar from I2" << std::endl;
}
};
int main (int argc, char** argv) {
I2* i = new C2();
i->foo();
i->bar();
return 0;
}
Voici l’erreur que j’obtiens:
test713.cpp: In function 'int main(int, char**)':
test713.cpp:26:16: error: invalid new-expression of abstract class type 'C2'
I2* i = new C2();
^
test713.cpp:17:8: note: because the following virtual functions are pure within 'C2':
struct C2: C1, I2 {
^~
test713.cpp:4:14: note: 'virtual void I1::foo()'
virtual void foo () = 0;
^~~
Il prétend ne pas pouvoir instancier mon objet C2 car la méthode virtuelle pure foo n’est pas définie. Pourtant, cette implémentation existe, puisque C2 étant C1 et C1 en définnit bien une implémentation.
A tout hasard j’ai essayé d’ajouter:
using C1::foo;
J’ai aussi essayé de changer l’ordre d’héritage:
struct C2: I2, C1 {
Mais ça ne change rien.
Si je redéfinis explicitement foo dans C2, ça fonctionne:
void foo () override {
C1::foo();
}
Pourquoi l’implémentation existante de C1::foo n’est pas automatiquement reprise dans C2 ?
Comment lui dire de réutiliser c1::foo sans la redéfinir explicitement ?
Dans mon cas concret, je ne n’ai pas le contrôle sur I1 et C1 qui font partie d’un framework (wxWidgets), et I1 définit plusieurs dizaines (si pas centaines) de méthodes virtuelles pures que C1 implémente déjà très bien. Dans C2, je redéfinis quelques-unes des méthodes de C1, mais je ne touche pas à la plupart d’entre-elles. J’aimerais bien éviter d’écrire du wrapper code parfaitement inutile.
Comment faire ?
Merci pour vos réponses.