Virtuelle C++ - Funktion versteckt
Ich habe ein problem mit C++ Vererbung.
Ich habe eine Klassen-Hierarchie:
class A {
public:
virtual void onFoo() {}
virtual void onFoo(int i) {}
};
class B : public A {
public:
virtual void onFoo(int i) {}
};
class C : public B {
};
int main() {
C* c = new C();
c->onFoo(); //Compile error - doesn't exist
}
Meine Frage ist: warum macht das nicht kompilieren? Mein Verständnis ist, dass C Erben sollen beide onFoo Funktionen von Ein - und in der Tat, diese kompiliert, wenn Sie entfernen die Neudefinition von onFoo in B, aber g++ gibt einen Fehler, der C hat keine onFoo () - Funktion.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das Problem, das Sie erleben, ist im Zusammenhang mit dem Namen lookup funktioniert in C++. Insbesondere, wenn er ein Mitglied der compiler wird der statische Typ des Objekts, auf dem die member zugegriffen wird. Wenn die id gefunden wird, in dieser Klasse, dann lookup abgeschlossen, und (im Fall von member-Funktionen) überlast Auflösung beginnt. Wenn der Bezeichner nicht gefunden wird, wird krabbeln die Hierarchie, Klasse von Klasse, versuchen, suchen Sie die Kennung eine Ebene in einer Zeit.
In Ihrem Fall, Sie haben
c->onFoo();
undc
ist der TypC
. Der compiler sieht nicht jede Erklärung deronFoo
imC
, so geht es weiter in der Hierarchie nach oben. Wenn der compiler prüftB
es sieht, dass es eine Erklärung dervoid onFoo(int i)
auf dieser Ebene, so dass es hält-lookup, und versucht überlast Auflösung. In dieser Zeit die überlast-resolution scheitert an der Inkonsequenz in der Argumentation.Die Tatsache, dass eine Erklärung der
void onFoo(int)
ist derzeitB
Ebene hat die Wirkung von versteckt den rest der überlasten in jedem Basis-Klasse, so wird es aufhören, zu suchen. Beachten Sie, dass dies ein problem mit unqualifizierten lookup, die Funktion ist immer noch da und ist anwendbar auf das Objekt, wird aber nicht gefunden werden durch regelmäßige lookup (Sie können es immer noch alsc->A::onFoo()
).Als der Umgang mit der versteckt, der einfachste Weg ist durch den Einsatz der using-Deklaration bringen die Funktionen in den Bereich:
Die Wirkung der
using
Erklärung hier ist, dass, wenn dieB
Klasse gesucht, die auf der Suche nach deronFoo
Bezeichner, den der compiler angewiesen, auch betrachten Sie alle überladungen vononFoo
in der Basisklasse, sodass regelmäßige lookup zu findenA::onFoo()
.Wenn Sie wollen Basisklasse Mitglieder zu überlasten abgeleitete Klasse, die Sie verwenden möchten
using
:Diesem Namen versteckt, im Grunde nur das erklärte überschreibungen existieren in B und die anderen überladungen, die in Einem verborgen sind.
Methoden auf der Klasse A und B sollen öffentlich sein. Dass, und Ihnen fehlt ein Semikolon am Ende jeder Klasse Erklärung.
Vergessen Sie
public:
modifier, bevor die Methoden in beiden Klassen A und B. Daher Methode onFoo ist privat und somit nicht sichtbar überall außerhalb dieser Klassen.Ich denke, dass Sie Sie verpasst haben, fügen Sie diese in
class B
:Nun diese kompiliert!