Mit Iterator auf Methoden von abgeleiteter Klasse zugreifen



  • Funktioniert auch nicht.





  • Das muss ja irgendwie gehen.


  • Mod

    @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 von Essen 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.



  • 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