Du bist nicht eingeloggt.

Login

Pass

Registrieren

Community
Szene & News
Locations
Impressum

Forum / Bits und Bytes

Verwendung von Listen in C++

Inception_ - 32
Profi (offline)

Dabei seit 05.2009
621 Beiträge

Geschrieben am: 31.05.2014 um 13:44 Uhr

Hi Com,

die Listen machen wir momentan schwer zu schaffen.
Ich habe zwei Klassen: "Artikel" und "Buch". Die Klasse "Buch" erbt Methoden und Attribute von "Artikel". Neben "Buch" soll es später noch viele andere von "Artikel" erbende Klassen geben. Mein Vorhaben ist alle erbenden Objekte in eine Liste (list<Artikel*> artikelliste) zu packen. Mein Problem besteht darin, dass ich nur auf Methoden der Klasse "Artikel" zugreifen kann.

[verlinkte Grafik wurde nicht gefunden]

Auf die Methode getX() kann ich momentan nicht zugreifen. Wie bekomme ich den Zugriff hin?



Science, 128√e980 .. :*

Apex91 - 34
Anfänger (offline)

Dabei seit 07.2013
13 Beiträge
Geschrieben am: 31.05.2014 um 14:33 Uhr

Ich muss direkt vorne weg sagen, in C++ habe ich derartiges bisher nicht verwendet.

In anderen objektorientierten Programmiersprachen ist es durchaus auch gängig, dass man derartige Listen, wie du sie beschreibst aufbauen kann.

Wenn du dann allerdings Methoden der Buch-Klasse verwenden möchtest musst du für dein Listenelement, das du gerade behandelst zuerst sicherstellen, ob es vom Typ "Buch" ist und anschließend einen Typecast zum Typ Buch durchführen.

Nach dem Typecast sollten die Methoden der Klasse problemlos verfügbar sein.

Wenn das zu kompliziert ist solltest du dir überlegen, ob deine Struktur überhaupt sinnvoll ist, oder ob es vielleicht sinnvoller wäre eine Liste von jedem erbendem Typ zu verwalten, anstatt alle in eine Liste zu packen.

Wie gesagt, meine Kenntnisse beziehen sich auf Erfahrungen mit Java und C#, nicht auf C++. Falls das dort grundlegend anders geht, verzeiht mir.
Inception_ - 32
Profi (offline)

Dabei seit 05.2009
621 Beiträge

Geschrieben am: 31.05.2014 um 14:46 Uhr
Zuletzt editiert am: 31.05.2014 um 14:46 Uhr

Danke für deine Antwort. Eine andere Struktur funktioniert und das würde ich auch hinbekommen. Allerdings ist das ein größeres Projekt, bei dem ich diese Vorgabe nicht ändern kann.
Ein Kommentar war, dass durch die Vererbung die Klasse "Buch" einen gleichen Zeiger wie "Artikel" hat und somit auf getX() zugegriffen werden kann. Oder zumindest so ähnlich.

Science, 128√e980 .. :*

Apex91 - 34
Anfänger (offline)

Dabei seit 07.2013
13 Beiträge
Geschrieben am: 31.05.2014 um 14:55 Uhr

Man hat bei Objekten mit Vererbung immer nur Zugriff auf die Methoden der Superklassen des momentanen Zeigers und der Klasse selbst natürlich.

Es würde ja keinen Sinn machen, wenn ich eine Liste von Zeigern auf Fahrzeuge speichere und bei einem Auto, das sich in der Liste befinde auf einmal fliegen() aufrufen könnte, nur, weil ich auch eine erbende Klasse Hubschrauber habe.

Aus dem Grund wirst du ohne Typecasts nicht auf deine setX Methode von Buch zugreifen können.

Wenn die Vorgabe tatsächlich so strikt ist, dann hast du evtl. die setX Methode in die flasche Klasse gepackt?
Für mich erscheint es jedenfalls sinnvoll für alle geführten Artikel eine Anzahl festzuhalten.
Dann wünsch ich dir noch viel Erfolg.
Inception_ - 32
Profi (offline)

Dabei seit 05.2009
621 Beiträge

Geschrieben am: 31.05.2014 um 15:01 Uhr
Zuletzt editiert am: 31.05.2014 um 15:03 Uhr

Zitat von Apex91:

Aus dem Grund wirst du ohne Typecasts nicht auf deine setX Methode von Buch zugreifen können.

Dann schau ich mal danach, vielen Dank.

Zitat von Apex91:


Wenn die Vorgabe tatsächlich so strikt ist, dann hast du evtl. die setX Methode in die flasche Klasse gepackt?
Für mich erscheint es jedenfalls sinnvoll für alle geführten Artikel eine Anzahl festzuhalten.
Dann wünsch ich dir noch viel Erfolg.

Nein, das ist es nicht. Jeder Artikel hat beispielsweise eine Artikelnummer oder einen Preis und diese Attribute sind auch in der Superklasse, aber wenn es jetzt Bücher und CD's gibt, dann hat eine CD keine Seitenzahl und ein Buch keine Dauer. Deswegen sitzen diese Attribute und deren zugehöreigen get()- und set()-Methoden in den zugehörigen Klassen.

Science, 128√e980 .. :*

Inception_ - 32
Profi (offline)

Dabei seit 05.2009
621 Beiträge

Geschrieben am: 31.05.2014 um 17:31 Uhr
Zuletzt editiert am: 31.05.2014 um 18:09 Uhr

Eine Professorin hat mir folgendes vorgeschlagen:

[verlinkte Grafik wurde nicht gefunden]

Man macht die Artikel-Klasse einfach abstrakt. Die Methoden getX() und setX(int zahl) der Kindklassen lassen sich jetzt ansteuern.

Danke für dein Bemühen Apex91

Science, 128√e980 .. :*

Apex91 - 34
Anfänger (offline)

Dabei seit 07.2013
13 Beiträge
Geschrieben am: 01.06.2014 um 04:17 Uhr

Ah natürlich,... das ist etwas, das in moderneren Sprachen eher über Interface-Klassen gehandhabt wird.

Eventuell weiß ich das beim nächsten Mal, wenn ich mal selbst mit C++ arbeite dann noch.
Das letzte Mal, dass ich mit C++ zu tun hatte war immerhin in der 12. Klasse, da vergißt man beinahe alles.
ItsPayne - 40
Profi (offline)

Dabei seit 12.2008
997 Beiträge

Geschrieben am: 01.06.2014 um 16:05 Uhr
Zuletzt editiert am: 01.06.2014 um 16:21 Uhr

Abstrakte Klassen sind Klassen die nicht zur Instanzierung gedacht sind, die Funktionen definieren die in den Kind-Klassen implementiert werden *müssen*.

Was die Professorin vorgeschlagen hat sind virtuelle Funktionen, was einfach bedeutet, die Funktion kann in einer abgeleiteten klasse überschrieben werden.

C# unterscheidet hier übrigens genauer als C++ es tut. Dort gibt es abstract sowie virtual jeweils als eigenes keyword.

Gängiger weise ist virtual weniger für Zugriffe (get, set..) auf Eigenschaften gedacht, sondern vielmehr für tatsächliche Funktionen, die prinzipiell die gleiche Aufgabe haben aber die Besonderheiten der Kind-Klasse berücksichtigen.

In deinem Beispiel kann man das zwar so verwenden, du musst wahrscheinlich aber sowieso zur Laufzeit wissen was für ein konkreter Typ sich hinter dem Objekt verbirgt, wo wir eh wieder bei Typprüfung/Casts wären.

Auch dort sind moderne Hochsprachen C++ mittlerweile überlegen, da diese meist die Möglichkeit spezieller Interface Klassen bieten um solche Themen strukturierter zu lösen.

Wenn du in der Mutterklasse viele virtuelle Funktionen definierst, die nicht in allen Kind-Klassen implementiert sind, dann wirst du das im Ablauf vermutlich eh wieder abfangen müssen, indem du einen Default return value prüfst der aussagt "nicht vorhanden".

Für zugriffe auf Eigenschaften würde ich daher eher mit Typprüfung/Casts arbeiten und virtuelle Funktionen dort verwenden wo tatsächlich eine Funktion aufgerufen werden soll, die alle prinzipiell unterstützen aber teilweise unterschiedlich ausgeführt werden müssen.

Wenn du lange genug in einen Abgrund blickst, blickt der Abgrund auch in dich hinein.

Rifleman - 40
Experte (offline)

Dabei seit 09.2003
1540 Beiträge
Geschrieben am: 02.06.2014 um 22:04 Uhr

Zitat von ItsPayne:

Abstrakte Klassen sind Klassen die nicht zur Instanzierung gedacht sind, die Funktionen definieren die in den Kind-Klassen implementiert werden *müssen*.

Was die Professorin vorgeschlagen hat sind virtuelle Funktionen, was einfach bedeutet, die Funktion kann in einer abgeleiteten klasse überschrieben werden.

C# unterscheidet hier übrigens genauer als C++ es tut. Dort gibt es abstract sowie virtual jeweils als eigenes keyword.

Artikel::getX() und ::setX(int) sind hier nicht nur virtual sondern pure virtual, damit ist Artikel abstrakt und man kann davon keine Objekte erzeugen.

Es sind die kleinen Dinge, die einen zum Wahnsinn treiben.

  [Antwort schreiben]

Forum / Bits und Bytes

(c) 1999 - 2025 team-ulm.de - all rights reserved - hosted by ibTEC Team-Ulm

- Presse - Blog - Historie - Partner - Nutzungsbedingungen - Datenschutzerklärung - Jugendschutz -