Mit Iterator auf Methoden von abgeleiteter Klasse zugreifen
-
Hallo zusammen,
ich bräuchte eure Hilfe.
Ich habe ein C++ Programm in visual studio geschrieben.Dies sieht folgendermaßen aus:
Ich habe eine Basisklasse + zwei weitere Klassen die von der Basisklasse
erben.
Funktion alles bereits.Jetzt gibt es noch eine 4 Klasse, die nichts vererbt bekommt.
Diese soll nur Verwalten.
In dieser Klasse habe ich eine Liste mit Iterator erstellt.
Nun möchte ich mit diesem Iterator auf die Methoden der abgeleiteten
Klassen zugreifen.
Leider findet der Iterator immer nur Methoden aus der Basisklasse, aber
nicht aus den beiden abgeleiteten, obwohl die Methoden public sind.So sieht meine Liste aus:
list <Bestellung*> liste; list <Bestellung*>::iterator it; // Hier möchte ich die Methode aufrufen: (*it)->...Methoden der abgeleiteten Klassen......;
Wie kann ich das machen?
-
Sollte eigentlich gehen.
virtual
vergessen? Ansonsten: Zeig mehr Code.
-
Hier das program ohne main und ohne der zweiten Klasse. Hat aber das gleiche Problem. #include <string> #include <iostream> #include <list> using namespace std; class Essen { protected: string produktbezeichnung; int produktID; public: Essen(string iniProduktbezeichnung, int iniProduktID) { produktbezeichnung = iniProduktbezeichnung; produktID = iniProduktID; } int getID() { return produktID; } }; class Lebensmittel : public Essen { private: struct Datum { int Tag; int Monat; int Jahr; }; Datum datum; public: Lebensmittel(string iniProduktbezeichnung, int iniProduktID, float inipreis, int iniLagerBestand, Datum iniDatum) :Essen(iniProduktbezeichnung, iniProduktID) { datum = iniDatum; } void displayLebensmittel() { cout << "Produktbezeichnung: " << produktbezeichnung << endl; cout << "Produkt-ID " << produktID << endl; cout << "Datum " << datum.Tag << "." << datum.Monat << "." << datum.Jahr << endl; } Datum getAblaufdatum() { return datum; } }; class Verwaltung { private: list <Essen*> liste; list <Essen*>::iterator it; public: Verwaltung() {}; void bestellungEinfügen(Essen* produkt) { liste.push_back(produkt); } void alleProdukteAnzeigen() { cout << "" << endl; cout << "Alle Bestellungen anzeigen des is!!!!" << endl; cout << "" << endl; for (it = liste.begin(); it != liste.end(); it++) { (*it)->displayLebensmittel; // Hier liegt das Problem } } }; void main() { // Teststruktur wurde jetzt nich angegeben. }
-
Deine Liste besteht ja aus
Essen*
-Elementen, aberdisplayLebensmittel
(btw.: es fehlt noch die Klammern für den Aufruf) gibt es dort nicht, sondern nur in der abgeleiteten Klasse 'Lebensmittel'.
Also entweder auch die Funktion alsvirtual
oderabstract (= 0)
in der Basisklasse definieren oder aber nurLebensmittel*
in der Liste zulassen.PS: Üblicherweise nimmt man
vector<T>
anstattlist<T>
(wenn man nicht hauptsächlich Elemente mittendrin hinzufügt).
Und der Iteratorit
sollte nur eine lokale Variable (kein Klassenmember sein) - es ist ja kein Zustandswert der KlasseVerwaltung
.
-
Funktioniert auch nicht mit den Klammern.
Kannst du mir im Code kurz zeigen, wie du das machen würdest?
Kann es nicht ganz nachvollziehen, wenn ich es nicht gesehen habe.Danke.
-
Füge
void displayLebensmittel() = 0;
in die Klasse
Essen
ein (bzw. die Funktion sollte dann nur jeweilsdisplay
o.ä. heißen).Noch besser, diese wäre
virtual
undEssen
würde selbst seine Daten (produktbezeichnung
,produktID
) ausgeben und die abgeleiteten Klassenfunktionen rufen dann diese Basisfunktion auf.
-
Funktioniert auch nicht.
-
@C91 sagte in Mit Iterator auf Methoden von abgeleiteter Klasse zugreifen:
Funktioniert auch nicht.
-
Das muss ja irgendwie gehen.
-
@C91 sagte in Mit Iterator auf Methoden von abgeleiteter Klasse zugreifen:
Das muss ja irgendwie gehen.
Geht ja auch, wenn man's richtig macht. Aber mit der Beschreibung "Funktioniert auch nicht." können wir dir halt nicht sagen, was du nicht richtig machst.
-
Ja, ich habe es hinbekommen, danke.
Aber jetzt habe ich noch ein problem.
virtual funktioniert bei mir nur, wenn die Methode keinen Rückgabewert hat.
virtual void displayGetränke() {};
So funktioniert es nicht mehr:
virtual int getTag() {};
Hier kommt immer die Fehlermeldung: C4716 Muss einen Wert zurückgeben.
So sieht die getter aus:
int getTag() { return ablaufdatum.Tag; }
Was mache ich jetzt falsch?
-
@C91 sagte in Mit Iterator auf Methoden von abgeleiteter Klasse zugreifen:
virtual int getTag() {};
Ist das in der Basisklasse? Wenn diese Methode
getTag()
dort keine sinnvolle Implementierung hat dann mach' sie pure virtual:virtual int getTag() const = 0;
-
Die getter ist in einer abgeleiteten Klasse.
-
Lebensmittel
ist vonEssen
abgeleitet? WTF?
-
@hustbaer
hat sich wahrscheinlich nen Wolf gelesen (vorsicht, insider).
-
@C91 sagte in Mit Iterator auf Methoden von abgeleiteter Klasse zugreifen:
Aber jetzt habe ich noch ein problem.
So funktioniert es nicht mehr:
virtual int getTag() {};
Hier kommt immer die Fehlermeldung: C4716 Muss einen Wert zurückgeben.
Was mache ich jetzt falsch?
Das geht auch ohne virtual nicht. Wenn die Methode einen Rückgabewert hat, dann muss sie auch etwas zurückgeben. Wie die Fehlermeldung schon sagt.
-
@C91: abgesehen von den Codefragen: was willst du eigentlich modellieren?
Ansonsten hilft dir vielleicht dieses Beispiel hier:
#include <iostream> #include <memory> class Basisklasse { public: int funktion_a(); virtual int funktion_b(); virtual int funktion_c() = 0; virtual ~Basisklasse() = default; // nicht vergessen! }; int Basisklasse::funktion_a() { return 42; } int Basisklasse::funktion_b() { return 23; } // funktion_c brauchen wir nicht, weil mit =0 als 'pure virtual' markiert class Kindklasse : public Basisklasse { public: int funktion_a(); int funktion_b() override; int funktion_c() override; int funktion_d(); }; int Kindklasse::funktion_a() { return 1; } int Kindklasse::funktion_b() { return 2; } int Kindklasse::funktion_c() { return 3; } int Kindklasse::funktion_d() { return 4; } int main() { std::unique_ptr<Basisklasse> pb = std::make_unique<Kindklasse>(); // (man sollte kein new benutzen) std::cout << pb->funktion_a() << '\n'; //42 weil nicht virtual std::cout << pb->funktion_b() << '\n'; //2 std::cout << pb->funktion_c() << '\n'; //3 // pb->funktion_d() geht nicht, weil es funktion_d nicht in Basisklasse gibt }
Edit: berichtigt.
-
@wob
funktion_a gibt 1 aus, und funktion_d geht auch ...
Es wurde die Klasse Kindklasse instanziert.
-
Tja, das passiert, wenn man zuviel
auto
benutzt.
Zu Fuß gehen ist viel umweltfreundlicher
-
@Belli sagte in Mit Iterator auf Methoden von abgeleiteter Klasse zugreifen:
@wob
funktion_a gibt 1 aus, und funktion_d geht auch ...
Es wurde die Klasse Kindklasse instanziert.Argh, kommt davon, wenn man zu viel vereinfachen will und das nicht testet. Habs berichtigt.