Hallo, also ich hab folgendes Problem, ich hab die Klassen Person, Mann und Frau. Ich moechte nun ein Programm schreiben (in C++) in der entweder ein Mann oder eine Frau die ganzen Funktionen ausfuehren und dies soll ueber einen Button entschieden werden. Ich hab jetzt daran gedacht das Mann und Frau von Person erben, ich ein Objekt von Person erzeug und dann einen Zeiger zwischen einem Mann und einem Frau Objekt hin und her bieg. Geht das? Wenn ja wie implementier ich das? Das Programm soll spaeter auch noch andere Klassen (aehnlich wie Frau und Mann :-)) erhalten, deshalb soll das Programm moeglichst einfach zu aendern sein und ich moechte nicht jede Funktion mit einem if Button abfragen welcher Button gedrueckt ist. Hoffe ihr koennt mir helfen und danke schonmal im Vorraus. Gruesse Gregor
:-) Nope leider nicht. Bin Student und lern grad C++. Ist keine Klassenarbeit etc.
Dann würde ich doch mal ein vernünftiges Buch über C++ nahelegen. Es ist etwas einfacher, wenn du das erstmal durcharbeitest, als wenn man hier alle Grundlagen einzeln vorkauen muß. Das ist nicht böse gemeint, aber so macht es doch keinen Sinn.
Danke fuer die Hilfe ... Ich kenn mich mit Zeigern auf Arrays usw. aus. Nur weiss ich halt nicht wie das mit Objekten funktioniert. Muessen Mann und Frau die gleichen Funktionen haben damit ich einen Zeiger auf Person legen kann und die Funktion dann ueber Person aufruf? Die einzelnen Funktionen von Mann und Frau unterscheiden sich naemlich inhaltlich.
Aber Du kennst Dich ganz offensichtlich mit C++ nicht aus. Normalerweise legt niemand in einer Instanz des Elternobjektes einen Zeiger auf die Instanz eines Kindobjektes an. Wozu auch? Das Kinndobjekt erbt ja alle Eigenschften. Beschreibe mal genauer die Problemstellung.
Gregor H. schrieb: > Ich kenn mich mit Zeigern auf Arrays usw. aus. > Nur weiss ich halt nicht wie das mit Objekten funktioniert. Dann würde ich doch mal ein vernünftiges Buch über C++ nahelegen.
Problem ist einfach ich hab 2 Objekte Mann und Frau und jeder hat z.B. die Methode laufen() also ich hab in meinem Code ... Mann.laufen() ... und jezt will ich das einfach durch Frau.laufen() austauschen. Ohne den Code zu veraendern und ich hab halt gedacht das ich Person.laufen() in den Code schreib und dann von Person einen Zeiger auf Mann bzw. Frau bieg. Hoff ich konnts jetzt einigermassen erklaeren und ihr koennt mir helfen. Sorry fuer die Missverstaendnisse.
Gregor H. schrieb: > ... die Missverstaendnisse. Diese wiederum legen den Gebrauch eines Buches nah. Tip: es geht nicht durch Umbiegen von Zeigern.
Ja wie loes ich das dann? Von mir aus sag mir halt nur das Stichwort wie ich so ein Problem angehen kann, dann schau ich selber nach ...
Also das mit der Vererbungshierarchie ist schon richtig. Du lässt Mann bzw. Frau von Person erben. Was du jetzt willst, habe ich jetzt so interpretiert, dass du eine Möglichkeit suchst einen Zeiger wahlweise auf ein Mann oder Frau Objekt zeigen zu lassen. Da geht mit Polymorphismus.
manche skriptsprachen wie Python und Ruby haben duck-typing (siehe wiki) C++ muss zumindest ist-ein Relationen zwischen Typen zur Compilierzeit wissen. Mensch hat 2 Arme. Mann ist ein Mensch. (hat also 2 Arme) Frau ist ein Mensch. (dito)
Japp, Polymorphie ist das Stichwort. Lang ists her mit C++, aber ich versuche es mal mit dem Person Mann Frau Beispiel. Die Konstruktoren etc. lass ich weg.
1 | class Person |
2 | { |
3 | public: |
4 | string name; |
5 | virtual void bewegen(Person *ziel){cout << "Ich " << this->name << " gehe zu " << ziel->name << endl;} |
6 | }; |
7 | class Mann : public Person{}; |
8 | class Frau : public Person{}; |
9 | class Baby : public Mann |
10 | { |
11 | void bewegen(Person *ziel){cout << "Ich " << this->name << " krabbel zu " << ziel->name << endl;} |
12 | }; |
13 | |
14 | void main() |
15 | { |
16 | Mann *peter = new Mann("Peter"); |
17 | Frau *renate = new Frau("Renate"); |
18 | Baby *martin = new Baby("Martin"); |
19 | |
20 | peter->bewegen(renate); |
21 | renate->bewegen(martin); |
22 | martin->bewegen(peter); |
23 | } |
>> Ich Peter gehe zu Renate >> Ich Renate gehe zu Martin >> Ich Martin krabbel zu Peter Viel Spass beim rumspielen!
Michael II schrieb: > Viel Spass beim rumspielen! Zu einem guten Polymorphiebeispiel würde das, wenn du folgendes machst
1 | void tellItToMove( Person* pers, Person* to ) |
2 | (
|
3 | pers->bewegen( to ); |
4 | )
|
5 | |
6 | void main() |
7 | {
|
8 | Mann *peter = new Mann("Peter"); |
9 | Frau *renate = new Frau("Renate"); |
10 | Baby *martin = new Baby("Martin"); |
11 | |
12 | tellItToMove( peter, renate ); |
13 | tellItToMove( renate, martin ); |
14 | tellItToMove( martin, peter ); |
15 | }
|
Die Funktion tellItToMove hat keinen blassen Schimmer davon, wer oder was pers ist. Trotzdem landet der Funktionsaufruf bewegen immer bei der richtigen Klasse. Bei deinem Beispiel ist das 'Problem' darin, das du mit expliziten Mann, Frau und Baby Pointern hantierst. Genau darum geht es ja bei Polymorphie: Das der genaue Typ des Objektes beim Aufruf der jeweiligen Funktion zur Compiletime eben nicht bekannt ist. Dein Beispiel würde auch ohne Polymorphie (also ohne virtuelle Funktionen) funktionieren.
Ok, ich glaube zu verstehen was du meinst. Ich habe die Polymorphie erst in der bewegen()-Funktion vollzogen, du aber außerhalb der abgeleiteten Klassen, was formal richtig ist, sehe ich das richtig? Und du hast recht, die Verwendung von 'virtual' ist nur nötig bei der Verwendung von Kopien der Person-Klasse, in diesem Fall also nicht da Person* benutzt wurde (frühe/späte Bindung). Wie schnell man doch vergisst, wenn man es nicht anwendet. :-) MfG
@Michael II: In deinem Beispiel gibt es keine Polymorphie. Die kommt erst ins Spiel, wenn an einer Stelle eine Basisklasse bekannt ist (Person), in Wirklichkeit aber ein Objekt einer davon abgeleiteten Klasse (Mann, Frau, ...) vorliegt. Falls die entsprechenden Methoden virtual sind, werden dann korrekt die der abgeleiteten Klasse aufgerufen und nicht die der Basisklasse. In dem KHB-Beispiel: tellItToMove() glaubt, eine Person zu haben und kann nicht sehen, ob es zur Laufzeit wirklich eine Person ist, oder etwas davon abgeleitetes. Der Compiler kann also beim Aufruf von pers->bewegen() nicht wissen, was er tatsächlich aufruft (Person::bewegen(), Mann::bewegen(), Frau::bewegen(), ...). Wäre bewegen() nicht virtual, würde in jedem Fall Person::bewegen() genommen werden. Durch das virtual dagegen wird Code so erzeugt, daß zur Laufzeit dem jeweils aktuellen Objekt entnommen, welche Methode dazu gehört. Das ist nur möglich, wenn peter, renate und martin entweder als Zeiger oder Referenz übergeben werden. Michael II schrieb: > Und du hast > recht, die Verwendung von 'virtual' ist nur nötig bei der Verwendung von > Kopien der Person-Klasse Wenn peter, renate und martin als Kopie übergeben werden (also nicht Zeiger, nicht Referenz) ist virtual eben nicht wirksam. Dann passiert Folgendes: Beim Aufruf werden peter etc. in eine Person gecastet. Innerhalb der aufgerufenen Funktion ist es damit Person, und (unabhängig von virtual oder nicht) wird in jedem Fall Person::bewegen() verwendet; die Kopie ist ja nicht mehr Mann oder Frau.
Danke für die Aufklärung. Ich habe grad mein altes Skript ausgebuddelt und nochmal nachgeschlagen. Es wird etwas unglücklich erklärt, aber richtig. Ich hatte es anscheinend nie richtig verstanden. Ich muss zugeben nie ein C++ Buch bessesen zu haben, das wird sich ändern. MfG
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.