Mit Iterator auf Methoden von abgeleiteter Klasse zugreifen



  • @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.



  • Hier das Beispiel, wie ich es versuche.
    Ich möchte die getter aus der Klasse Lebensmittel in der Verwaltung mit dem Iterator aufrufen. Genau wie es beim ersten beispiel mit der display Methode.
    Dafür habe ich jetzt die folgendes gemacht.

    #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;
      	}
             
               virtual int getAblaufdatum(){}; // Das funktioniert nicht, mit void funktioniert es.
                // ich muss aber einen int zurückgeben.   
      };
      
      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;
      	}
      
      	int getAblaufdatum() {
      		return datum.Tag; // Hier ist die getter.
      	}
      };
      
      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; 
      		}
      	}
      };
      
      void main() {
      
      	// Teststruktur wurde jetzt nich angegeben.
      
      }


  •        virtual int getAblaufdatum(){}; // Das funktioniert nicht, mit void funktioniert es.
    

    Du darfst hier nicht {} schreiben, sondern du brauchs = 0;
    Also:
    virtual int getAblaufdatum() = 0;



  • Danke hat funktioniert.



  • Das Hinzufügen aller möglichen Zugriffsmethoden zur Basisklasse ist aber designtechnisch schlecht und hilft überhaupt nicht dabei OOP zu verstehen.

    Entweder jedes Essen hat ein Ablaufdatum, aber dann gehört auch dieses selbst in die Basisklasse oder aber nur die abgeleitete Klasse Lebensmittel hat ein Ablaufdatum und somit entsprechende Zugriffsfunktionen (auch wenn man dann nicht direkt per Essen*darauf zugreifen kann, sondern casten muß).

    Welche anderen von Essen abgeleiteten Klassen könnte es denn noch geben (so daß dieses Beispiel einen Sinn ergibt)?



  • Desweiteren rate ich zu einem C++-Fachbuch. Das hier riecht nach C-mit-Klassen, was man grundsätzlich unnötig ist.
    Was darüber hinaus empfehlenswert ist: Die Nutzung von "override" bei Funktionen die etwas überladen.



  • @It0101 sagte in Mit Iterator auf Methoden von abgeleiteter Klasse zugreifen:

    Die Nutzung von "override" bei Funktionen die etwas überladen.

    überschreiben 😉


Anmelden zum Antworten