Redefinieren: Satz aus meinem Buch verstehe ich nicht.
-
So also ich habs irgendwie so teilweise kapiert, ich weiß zwar eigentlich wie man es anwendet aber mit den Bezeichnungen habe ich noch Probleme.
Das hier wäre ja jetzt Redefinieren (da gleicher Rückgabetyp und gleiche Signatur):#include <iostream> using namespace std; class Tier { public: Tier() {}; ~Tier() {}; void Speak() {cout << "TIER\n";} }; class Hund : public Tier { public: Hund() {}; ~Hund() {}; void Speak() {cout << "HUND\n";} //wird hier redefiniert, da ja schon mal in Basisklasse Tier }; int main() { Tier BigAnimal; Hund Bob; BigAnimal.Speak(); Bob.Speak(); return 0; }Aber was wäre den dann bitte das hier? Nach Definition: "Erzeugt eine abgeleitet Klasse eine Funktion mit demselben Rückgabetyp und derselben Signatur wie eine Elementfunktion in der Basisklasse, aber mit einer neuen Implementierung, spricht man vom "Redefinieren" oder "Überschreiben" dieser Methode." kann es ja nicht Redefinieren sein! Aber für mich ist das eigentlich trotzdem das gleiche.
#include <iostream> using namespace std; class Tier { public: Tier() {}; ~Tier() {}; void Speak(int a) {cout << "TIER " << a << "\n";} }; class Hund : public Tier { public: Hund() {}; ~Hund() {}; int Speak() {cout << "HUND\n"; return 120; } }; int main() { Tier BigAnimal; Hund Bob; BigAnimal.Speak(5); Bob.Speak(); return 0; }Dankeschön schon mal im Voraus.
-
neine, es ist keine redifinition, es ist eine überladung, d.h., wenn du jetzt in deiner klasse "Hund" die methode "speak" aufrufen und ihr einen int-wert als parameter mitgeben würdest, würde die implementation aus der "tier"-klasse aufgerufen werden.
mfg,
julian
-
Also äh hab das vll. falsch verstanden, aber sowie ich es verstanden habe funktioniert es bei mir nicht.
#include <iostream> using namespace std; class Tier { public: Tier() {}; ~Tier() {}; void Speak(int a) {cout << "TIER " << a << "\n";} }; class Hund : public Tier { public: Hund() {}; ~Hund() {}; int Speak() {cout << "HUND\n"; return 120; } }; int main() { Tier BigAnimal; Hund Bob; BigAnimal.Speak(5); Bob.Speak(10); return 0; }Compiling: C:\MinGW\Andi\ÜberschreibenÜberdeckenÜberladen.cpp
C:\MinGW\Andi\ÜberschreibenÜberdeckenÜberladen.cpp: In functionint main()': C:\\MinGW\\Andi\\ÜberschreibenÜberdeckenÜberladen.cpp:27: error: no matching function for call toHund::Speak(int)'
C:\MinGW\Andi\ÜberschreibenÜberdeckenÜberladen.cpp:17: note: candidates are: int Hund::Speak()
Process terminated with status 1 (0 minutes, 0 seconds)
2 errors, 0 warningsDankeschön schon mal im Voraus.
-
Ja das hat was mit der Namensuche zu tun. Sollte eigentlich in dem Link stehen ...
Habe jetzt keine Lust das zu erklären
, deswegen verweise ich mal an die Stelle ... ( Ich hoffe Hume hat nichts dagegen )Generell läuft die Suche nach der passenden Funktion in drei Schritten ab:
1. Bildung der Kandidatenmenge
2. Auswahl der Funktionen mit passender Signatur aus der Kandidatenmenge
3. Auswahl der am Besten passenden FunktionAusgehend vom Scope in dem der Aufruf steht, kommen alle die Funktionen in die Kandidatenmenge, die den selben Namen haben wie die aufzurufende Funktion. Existiert in dem Scope keine solche Funktion, wird der darüberliegende Scope durchsucht. Umschließende Scopes werden also nur berücksichtigt, wenn in den eingeschlossenen Scopes keine gleichnamige Funktion existiert.
Das markierte ist wichtig, d.h. er hört dann auf zu suchen und würde nie Tier::Speak(int) finden, weil er schon eine Funktion mit dem Namen Speak in Hund gefunden hat ....
So nebenbei: Man sollte nicht-virtuelle Memberfunktion nicht redefinieren.
Spiele mal was mit Zeigern und so rum dann wirst du sehen, wieso etwas sich nicht so verhält wie es sollte
( Steht in Effective C++ was dazu )
[Jaja ich verweise gerne auf das Buch
]Edit: In Exceptional steht auch ne Menge zu Überladen/Überdecken etc ...

-
Ich hab den Link jetzt nochmal richtig durchgearbeitet (http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=oho#note_four) undauch alles gecheckt! Na na fast alles. Siehe folgendes Beispiel (sowas ähnliches kam auch in dem Link vor):
#include <iostream> using namespace std; class Tier { public: Tier() {}; ~Tier() {}; void func(int a); int func(); }; void Tier::func(int a) { cout << "INT" << endl; } int Tier::func() { cout << "VOID" << endl; } class Hund : public Tier { public: Hund() {}; ~Hund() {}; void func(float a); }; void Hund::func(float a) { cout << "FLOAT" << endl; } int main() { Hund A; Tier &B=A; return 0; }Was macht den genau:
Tier &B=A;?????
Das würde ja heißen: "B ist eine Referenz auf eine Tier Objekt" Ja? Aber A ist doch ein Hund Objekt! Also äh hat das was mit Polymorphie zu tun? Ist "Tier &B=A" sowas wie "Tier *B= new Hund"? Sowas kenn ich nämlich schon. Aber sowas wie "Tier &B=A;" hab ich noch nie gesehen (peinlich?). Also in meinem ganzen C++ Buch kam sowas noch nicht vor. Mhh vll.ste ich ja jetzt auch auf der Leitung. Kann mir vll. jemand auf die Sprünge helfen?
Dankeschön schon mal im Voraus.
-
Stromberg schrieb:
Was macht den genau:
Tier &B=A;?????
Das würde ja heißen: "B ist eine Referenz auf eine Tier Objekt" Ja? Aber A ist doch ein Hund Objekt! Also äh hat das was mit Polymorphie zu tun? Ist "Tier &B=A" sowas wie "Tier *B= new Hund"? Sowas kenn ich nämlich schon. Aber sowas wie "Tier &B=A;" hab ich noch nie gesehen (peinlich?). Also in meinem ganzen C++ Buch kam sowas noch nicht vor. Mhh vll.ste ich ja jetzt auch auf der Leitung. Kann mir vll. jemand auf die Sprünge helfen?
Dankeschön schon mal im Voraus.Doch haste bestimmt schonmal gesehen

void func(const Tier& obj); void othfunc(Tier& obj); //... Hund lessie, jimmy; func(lessie); othfunc(jimmy);Referenzparameter !
Ist nicht das selbe wie Tier *B= new Hund sondern (fast):
Hund lessie; Tier *obj = &lessie;
-
Ja, das hast Du schon selbst vollkommen richtig erkannt

Was die Kombination von Zeiger und Referenz angeht, die ist dabei vollkommen beliebig
Hund h1; // Hund auf Stack Hund* h2 = new Hund(); // Hund auf Heap Tier& a = h1; // a ist Referenz auf das Tier im Hund h1 Tier* b = h2; // b ist Zeiger auf das Tier im Hund *h2 // Mischen possible: Tier* d = &h1; // d ist Zeiger auf das Tier im Hund h1 Tier& c = *h2; // c ist Referenz auf das Tier im Hund *h2;
-
Okay kapiert!!! Nicht schwer eigentlich

So ich hätte da noch eine Frage zu dem Link. Siehe folgendes Beispiel (rauskopiert):class A { public: virtual void func(); // #1 void gunc(); // #2 }; class B : public A { public: using A::func; virtual void func(int); // #3 virtual void gunc(); // #4 }; class C : public B { public: void func(); // #5 void gunc(int); // #6 void gunc(); // #7 }; int main() { C c; A& rac = c; B& rbc = c; rac.func(); rac.func(2); rac.gunc(); rac.gunc(2); rbc.func(); rbc.func(2); rbc.gunc(); rbc.gunc(2); c.func(); c.B::func(2); c.gunc(); c.gunc(2); B b; A& rab = b; rab.func(); rab.func(2); rab.gunc(); rab.gunc(2); b.func(); b.func(2); b.gunc(); b.gunc(2); }In Zeile 9 steht was mit "using A::func;"! (also das kam echt nicht in meinem Buch vor, using)
Mh ich glaube zwar zu wissen was es bedeutet. Heißt das in etwa sowas wie "schreibe hier in Klasse B nochmal die gleiche Methode hin wie aus Klass A" das da der Code so übernommen wird? Sowas wie ein Makro der Compiler schreibt einfach den Code hin bzw. übernimmt dann die selbe Methode von Klasse A mit Deklaration + Definition für B??? Nääää oder?
Kann mir das jemand erklären? Wäre sichere, als das ich mir das irgendwas zusammenreime
Dankeschön schon mal im Voraus.PS: Ich bin schon lernfähig, nicht das sich jemand denkt der frägt bei jedem "sch***dreck" gleich im Forum. Aber ich bin mir halt echt nicht so ganz sicher was das heißt. In diesem Sinne, hoffentlich fühlt sich keiner gestört.
-
also damit wird die Methode der Basisklasse auch in der abgeleiteten "sichtbar".
hier nochmal das Bsp. von vorhin das mithilfe der using-direktive klappen sollte.#include <iostream> using namespace std; class Tier { public: Tier() {}; ~Tier() {}; void Speak(int a) {cout << "TIER " << a << "\n";} }; class Hund : public Tier { public: Hund() {}; ~Hund() {}; int Speak() {cout << "HUND\n"; return 120; } }; int main() { Tier BigAnimal; Hund Bob; BigAnimal.Speak(5); Bob.Speak(10); };wenn du jetzt Bob.Speak(10) aufrufst, dann gab es zuvor eine Fehlermeldung weil keine Funktion bekannt war die int als Parameter hat UND gleichzeitig eine Memberfunktion von Hund ist. Jetzt kann die Methode Speak() der Basisklasse aber auch bei Hund verwendet werden.

-
mist! das beispiel hab ich rauskopiert und vergessen das neue in die zwischenablage zu kopieren ...

hier das richtige...#include <iostream> using namespace std; class Tier { public: Tier() {}; ~Tier() {}; void Speak(int a) {cout << "TIER " << a << "\n";} }; class Hund : public Tier { public: Hund() {}; ~Hund() {}; using Tier::Speak; int Speak() {cout << "HUND\n"; return 120; } }; int main() { Tier BigAnimal; Hund Bob; BigAnimal.Speak(5); Bob.Speak(10); return 0; }