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 geht das?
:
Verschoben durch Moderator
Wie kann ich die komplette liste einfach auf der Konsole ausgeben?
helpme91 schrieb: > // Hier möchte ich die Methode aufrufen: > (*it)->...Methoden der abgeleiteten Klassen......; > > Wie geht das? Nur mit cast. Was natürlich ein saublöde Lösung wäre, weil dann für alle Fälle möglicher Erben verzweigt werden müsste. Oder anders ausgedrückt: Dein Konzept ist grundfalsch.
Wenn ich dein Problem richtig verstanden habe, fehlt dir virtual vor den Methoden, die du aufgerufen haben willst. Ohne das virtual kommt der Compiler nicht auf die Idee, in den Ableitungen nach einer Methode zu suchen.
1 | // Time-stamp: "18.09.21 18:30 bestellung.cpp klaus.wachtler@esolutions.de"
|
2 | //
|
3 | // g++ -Wall --std=c++17 bestellung.cpp -o bestellung && ./bestellung
|
4 | |
5 | #include <iostream> |
6 | #include <string> |
7 | #include <list> |
8 | |
9 | |
10 | class Bestellung |
11 | {
|
12 | public:
|
13 | Bestellung( const std::string &name ) |
14 | : name( name ) |
15 | {
|
16 | }
|
17 | |
18 | virtual void zeigDich() |
19 | {
|
20 | std::cout << "ich bin eine Bestellung " << name << std::endl; |
21 | }
|
22 | |
23 | protected:
|
24 | std::string name; |
25 | };
|
26 | |
27 | class Expressbestellung: public Bestellung |
28 | {
|
29 | public:
|
30 | Expressbestellung( const std::string & name ) |
31 | : Bestellung( name ) |
32 | {
|
33 | }
|
34 | |
35 | virtual void zeigDich() |
36 | {
|
37 | std::cout << "ich bin eine Expressbestellung " << name << std::endl; |
38 | }
|
39 | };
|
40 | |
41 | class Schneckenbestellung: public Bestellung |
42 | {
|
43 | public:
|
44 | Schneckenbestellung( const std::string & name ) |
45 | : Bestellung( name ) |
46 | {
|
47 | }
|
48 | |
49 | virtual void zeigDich() |
50 | {
|
51 | std::cout << "ich bin eine Schneckenbestellung " << name << std::endl; |
52 | }
|
53 | };
|
54 | |
55 | |
56 | int main( int nargs, char **args ) |
57 | {
|
58 | std::list< Bestellung* > meineliste; |
59 | meineliste.push_back( new Bestellung( "per Bote" ) ); |
60 | meineliste.push_back( new Expressbestellung( "UPS" ) ); |
61 | meineliste.push_back( new Schneckenbestellung( "DHL kommt vielleicht auch irgendwann an" ) ); |
62 | |
63 | for( auto it: meineliste ) |
64 | {
|
65 | it->zeigDich(); |
66 | }
|
67 | return 0; |
68 | }
|
Gibt bei mir aus:
1 | klaus@lap7:~$ g++ -Wall --std=c++17 bestellung.cpp -o bestellung && ./bestellung |
2 | ich bin eine Bestellung per Bote |
3 | ich bin eine Expressbestellung UPS |
4 | ich bin eine Schneckenbestellung DHL kommt vielleicht auch irgendwann an |
Lasse ich die virtual weg, kommt nur noch:
1 | klaus@lap7:~$ g++ -Wall --std=c++17 bestellung.cpp -o bestellung && ./bestellung |
2 | ich bin eine Bestellung per Bote |
3 | ich bin eine Bestellung UPS |
4 | ich bin eine Bestellung DHL kommt vielleicht auch irgendwann an |
Das heißt, es wird ohne virtual immer die Methode aus der Basisklasse genommen.
:
Bearbeitet durch User
Beitrag #6824769 wurde von einem Moderator gelöscht.
c-hater schrieb im Beitrag #6824769: > Letztlich ist es also (wie so oft) ein trade off zwischen Speicherbedarf > und Rechenzeit, welche der beiden Möglichkeiten man verwendet. Deswegen > habe ich oben das "richtig" auch in Anführungszeichen gesetzt. Um > anzudeuten, dass es manchmal durchaus auch richtig (im Sinne von > "sinnvoll") sein kann, das eigentlich falsche und verpönte zu tun... Nein, ist es (hier zumindest) absolut nicht. Der "richtige" Weg ist auch ohne Anführungsstriche der richtige, der andere ist Murks. Hast du doch selbst schon gesagt: c-hater schrieb: > Nur mit cast. Was natürlich ein saublöde Lösung wäre, weil dann für alle > Fälle möglicher Erben verzweigt werden müsste. > > Oder anders ausgedrückt: Dein Konzept ist grundfalsch. Außer dem "Nur" hattest du doch recht. Bleib doch dann auch dabei...
Klaus W. schrieb: > Nein, ist es (hier zumindest) absolut nicht. > Der "richtige" Weg ist auch ohne Anführungsstriche der richtige, der > andere ist Murks. Das weisst du woher? Also ich jedenfalls bräuchte für diese Entscheidung zumindest drei Informationen: 1) Anzahl der Erben-Klassen 2) Anzahl der Objekt-Instanzen 3) Menge des verfügbaren Speichers Selbst wenn man mal annehmen wollte, dass zumindest Punkt 1 mit dem TO erschöpfend behandelt ist, bleiben da doch noch zwei sehr wesentliche Punkte... Also ich würde sowas nicht mit deiner Stringenz entscheiden wollen OHNE die Kenntnis dieser Fakten... Aber was weiss ich schon, ich programmiere ja erst seit 40 Jahren und verdiene seit 30 Jahren meinen Lebensunterhalt damit... Aber ja: vor ca. 30 Jahren hätte ich vielleicht noch genauso argumentiert wie du. Da hatte ich ungefähr gerade den OO-Kram wirklich verstanden und fand das endlos geil. Aber: man lernt dazu...
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.