Überladung und Vererbung
-
Hallo zusammen,
ich habe ein Problem bei Überladung im Zusammenhang mit Vererbung.
Wieso ist folgendes Beispiel fehlerhaft, da doch in C++ Funktionen/Methoden überladen werden können?
class Basis { public: virtual void Test(int* x) { cout << "Basis";}; //!warning: `virtual void Basis::Test(int*)' was hidden }; class Derived : public Basis { public: virtual void Test(double, bool) { cout << "Derived";}; }; int main() { Derived d1; int*i; d1.Test(i); //!error: no matching function for call to `Derived::Test(int*&)' }
Wieso ist die Methode der Basisklasse in der abgeleiteten Klasse nicht sichtbar?
Auf Grund der Überladung (unterschiedliche Übergabeparameter) sind diese Methoden doch eindeutig.Ich hoffe ihr könnt mir helfen, für mich bricht eine C++-Welt zusammen
Schon mal Danke
-
Sobald du in der abgeleiteten Klasse eine Methode mit gleichem Namen wie in der Basisklasse deklarierst, ist die Basisklassenmethode nicht mehr sichtbar. Man spricht in diesem Zusammenhang von Verdeckung.
Die Basisklassenmethode kann man dennoch explizit aufrufen:
d1.Basis::Test(i);
-
Hi,
durch die Vererbung verdeckst du das Test aus der Basisklasse und da hier auch nicht die Parameter übereinstimmen, wird auch nichts überschrieben.
-
Kannst auch
class Derived : public Basis { public: using Base::Test(int*); //syntax ok?? grad keinen compiler zur Hand virtual void Test(double, bool) { cout << "Derived";}; }; verwenden
-
Hallo zusammen,
danke für die schnellen Antworten.
Ich denke ich habe es verstanden und meine C++Welt ist doch noch nicht untergegangen
Ich habe gelesen, dass ein Überladen von Methoden nur im selben Gültigkeitbereich möglich ist.
Anscheinend besagt die Regel zum "name lookup" bei Ableitungen, dass der Compiler in der Ableitung nach der Methode sucht. Hat er die Methode mit gleichem Namen gefunden, dann wird die Basisklasse nicht weiter betrachtet. Das bedeutet, dass alle anderen Methode mit gleichem Namen aber unterschiedlichen Parametern, in der Basisklasse verdeckt werden.Gruß
inaj76
-
Man kann ja wie oben beschrieben die Funktion der Basisklasse explizit aufrufen, was z.B. beim Konstruktor öfter mal Sinn macht, wenn der Konstruktor der Basisklasse wichtige Funktionen enthält, die beim Aufruf des Konstruktors der abgeleiteten Klasse notwendig sind. In diesem Fall ist es sicher sinnvoll den Konstruktor der Basisklasse explizit aufzurufen.