www.mikrocontroller.net

Forum: PC-Programmierung Zeigerproblem


Autor: Gregor H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welche Klasse und wann ist Abgabe?

Autor: Gregor H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:-) Nope leider nicht.
Bin Student und lern grad C++.
Ist keine Klassenarbeit etc.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Gregor H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Nobody (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Gregor H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gregor H. schrieb:
> ... die Missverstaendnisse.

Diese wiederum legen den Gebrauch eines Buches nah.

Tip: es geht nicht durch Umbiegen von Zeigern.

Autor: Gregor H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ...

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Gregor H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Endlich mal ne brauchbare Antwort.
Danke!

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Autor: Michael II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

class Person
{
public:
   string name;
   virtual void bewegen(Person *ziel){cout << "Ich " << this->name << " gehe zu " << ziel->name << endl;}
};
class Mann : public Person{};
class Frau : public Person{};
class Baby : public Mann
{
   void bewegen(Person *ziel){cout << "Ich " << this->name << " krabbel zu " << ziel->name << endl;}
};

void main()
{
   Mann *peter = new Mann("Peter");
   Frau *renate = new Frau("Renate");
   Baby *martin = new Baby("Martin");

   peter->bewegen(renate);
   renate->bewegen(martin);
   martin->bewegen(peter);
}

>> Ich Peter gehe zu Renate
>> Ich Renate gehe zu Martin
>> Ich Martin krabbel zu Peter

Viel Spass beim rumspielen!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael II schrieb:

> Viel Spass beim rumspielen!

Zu einem guten Polymorphiebeispiel würde das, wenn du folgendes machst
void tellItToMove( Person* pers, Person* to )
(
  pers->bewegen( to ); 
)

void main()
{
   Mann *peter = new Mann("Peter");
   Frau *renate = new Frau("Renate");
   Baby *martin = new Baby("Martin");

   tellItToMove( peter, renate );
   tellItToMove( renate, martin );
   tellItToMove( martin, peter );
}

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.

Autor: Michael II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Michael II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.