====== Funktionen aus der Basisklasse überschreiben ====== Für dieses Kapitel schauen wir uns kurz noch einmal unsere Tier-Klassen aus der [[cpp:inheritance:start|Einführung in die Vererbungslehre]] an und erweitern die Hund-Klasse um die Funktion ''GibNamenAus( char const * familyName )'': class Tier { public: char Name[64]; int Fellfarbe; int KrallenLaenge; int AnzahlBeine; inline void GibNamenAus( void ) { printf( "Ich heiße %s\n", Name ); }; class Hund : public Tier { public: int GefangeneKatzen; inline void GibLaut( void ) { printf( "Wau!\n"; } inline void GibNamenAus( char const * familyName ) { printf( "Ich heiße %s %s\n", Name, familyName ); } }; Nun wollen wir das folgende Programm ausführen: int main( void ) { Hund harry( "Harry" ); harry.GibNamenAus(); return EXIT_SUCCESS; } Wie immer ist der Code gekürzt, so fehlen z.B. die Konstruktoren. Den vollständigen Code gibt es [[cpp:overload:using:withoutusing|hier]]. Der Compiler meldet hierfür: withoutusing.cpp: In function ‘int main()’: withoutusing.cpp:50: error: no matching function for call to ‘Hund::GibNamenAus()’ withoutusing.cpp:34: note: candidates are: void Hund::GibNamenAus(const char*) Er kennt also die Funktion Hund::GibNamenAus() ohne Parameter nicht mehr. Die Methode wurde mit ''void GibNamenAus( char const * familyName )'' überladen. Wird eine Methode überladen, so werden alle bereits bekannten Möglichkeiten aus dem Namensraum entfernt. Darum kennt der Namensraum der Klasse ''Hund'' die Methode ''GibLaut()'' ohne Parameter nicht mehr. ===== explizite Nennung des Namensraums ===== Wir wissen bereits, dass vererbte Fähigkeiten nicht verloren gehen, wir können also darauf aufmerksam machen, dass es die gewünschte Methode im Namensraum der Basisklasse ''Tier'' gibt: int main( void ) { Hund harry( "Harry" ); harry.Tier::GibNamenAus(); return EXIT_SUCCESS; } Das funktioniert. Häufig ist das aber gar nicht der Wunsch des Entwicklers, oftmals möchte man eine weitere Methode den vorhandenen hinzufügen, so dass man die vererbten Funktionen weiterhin auch aus dem Namensraum der Klasse ''Hund'' rufen kann, ohne den Namensraum der Klasse ''Tier'' voranzustellen. ===== Methoden nicht aus dem Namensraum entfernen ===== Hierfür verwendet man das Schlüsselwort ''using''. ''using'' gilt immer für alle geerbten Methoden der gewählten Basisklasse, daher werden auch keine Rückgabewerte oder Parameter angegeben: class Hund : public Tier { public: int GefangeneKatzen; inline void GibLaut( void ) { printf( "Wau!\n"; } using Tier::GibNamenAus; inline void GibNamenAus( char const * familyName ) { printf( "Ich heiße %s %s\n", Name, familyName ); } }; So lässt sich nun die Funktion wie gewünscht in beiden Varianten rufen, ohne den Namensraum explizit angeben zu müssen. Der kompilierfähige Quelltext findet sich [[cpp:overload:using:withusing|hier]].