stl problem versch. klassen in einem container



  • so hab da n (kleines) problem ;P

    Zur Frage:

    In einem Conatiner sollen Objekte von verschiedenen Klassen(eine haupt und eine unterklasse die erbt) gespeichert werden.

    Wie kann man es realisieren das beim eintragen von einer Kaffeemaschine (siehe main.cpp) die Klasse Kaffeemaschine bei der funktion GeraetEintragen() benutzt wird und nicht AllgemeinesGeraet.

    Weiteres Problem besteht darin wie man dann in GeraetEintragen das Attribut iAnzahlTassen verwendet.

    fragen über fragen
    gruesse quibb

    #include "Geraete.h"
    #include <iostream>
    using namespace std;
    
    int main(void) {
    
    AllgemeinesGeraet test;
    
    Kaffeemaschine geraet1("bla", 1);
    
    test.GeraetEintragen(geraet1);
    
    cout << test;
    
    return 0;
    }
    
    #include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    class AllgemeinesGeraet {
    
    vector<AllgemeinesGeraet> Geraet;
    
    private:
    
    string sGeraetBezeichnung;
    
    public:
    
    AllgemeinesGeraet();
    AllgemeinesGeraet(string sBezeichnung);
    
    void GeraetEintragen(AllgemeinesGeraet &b) { // <-PROBLEM
    
    Geraet.push_back(b);
    }
    
    friend ostream& operator<<(ostream& os, AllgemeinesGeraet &test) {
    
    vector<AllgemeinesGeraet>::iterator pos;
    
    for (pos = test.Geraet.begin(); pos < test.Geraet.end(); ++pos)
    {
    os << *pos << endl;
    }
    
    os << "Bezeichnung: " << test.sGeraetBezeichnung;
    return os;
    }
    };
    
    class Kaffeemaschine : public AllgemeinesGeraet {
    
    private:
    
    int iAnzahlTassen;
    
    public:
    
    Kaffeemaschine(string sBezeichnung, int iTassen);
    };
    


  • Pointer



  • also?

    #include "Geraete.h"
    #include <iostream>
    using namespace std;
    
    int main(void) {
    
    	AllgemeinesGeraet test;
    
    	Kaffeemaschine geraet1("bla", 1);
    	Kaffeemaschine *p_geraet1 = &geraet1;
    
    	test.GeraetEintragen(*p_geraet1);
    
    	cout << test;
    
    	return 0;
    }
    


  • Pointer im Container



  • Du musst anstatt von:

    vector<AllgemeinesGeraet> Geraet;
    

    das schreiben:

    vector<AllgemeinesGeraet*> Geraet;
    

    Außerdem Anstatt von einer Referenz ebenfalls Zeiger übergeben. Dann sollte der Container in der Lage sein alle abgeleiteten Klassen von "AllgemeinesGeraet" zu speichern



  • erstmal vielen dank für den tip.
    hab jetzt einen pointer im container aber der sinn will sich mir immer noch nicht erschließen. Der Typ is doch trotzdem noch AllgemeinesGeraet 😞

    #include <vector>
    #include <string>
    #include <iostream>
    using namespace std;
    
    class AllgemeinesGeraet {
    
    	vector<AllgemeinesGeraet*> Geraet;	
    
    	private:
    
    		string sGeraetBezeichnung;
    
    	public:
    
    		AllgemeinesGeraet();
    		AllgemeinesGeraet(string sBezeichnung);
    
    		void GeraetEintragen(AllgemeinesGeraet *b) {
    
    			b->Geraet.push_back(this);			
    		}		
    
    		friend ostream& operator<<(ostream& os, AllgemeinesGeraet *b){				
    
    			os << b->sGeraetBezeichnung;						
    
    			return os;
    		}
    
    		void ausgabe() {
    
    			vector<AllgemeinesGeraet*>::iterator pos;
    			for (pos = Geraet.begin(); pos < Geraet.end(); ++pos)
    			{								
    				cout << *pos << endl;				
    			}
    		}	
    };
    
    class Kaffeemaschine : public AllgemeinesGeraet {
    
    	private:
    
    		int iAnzahlTassen;
    
    	public:
    
    		Kaffeemaschine(string sBezeichnung, int iTassen);
    };
    
    int main(void) {
    
    	AllgemeinesGeraet TestGeraet;
    	AllgemeinesGeraet *p_TestGeraet = &TestGeraet;
    
    	Kaffeemaschine geraet1("bla", 1);
    	Kaffeemaschine *p_geraet1 = &geraet1;
    
          p_geraet1->GeraetEintragen(p_TestGeraet);
    
          p_TestGeraet->ausgabe();
    
    	return 0;
    }
    

    gruss quibb



  • Falls du in dem Container eine normale Klasse (nicht als Zeiger) speicherst, dann erwartet der container diese Klasse am Ende auch.
    Wenn du stattdessen einen Zeiger verwendest, wird in dem Container nur die Adresse von dem Objekt im Speicher gespeichert und nicht das Objekt selbst.
    Das ermöglicht die auch abgeleitete Klassen innerhalb deines Containers zu speichern.



  • quibb schrieb:

    erstmal vielen dank für den tip.
    hab jetzt einen pointer im container aber der sinn will sich mir immer noch nicht erschließen. Der Typ is doch trotzdem noch AllgemeinesGeraet 😞

    Da hast du recht. Sinn macht das erst wenn Polymorphie ins Spiel kommt. Wenn du über einen pointer auf die Basisklasse eine virtuelle Methode aufrufst dann wird zur Laufzeit die richtige aufgerufen.

    Übrigens erzeugst du die Objekte besser dynamisch mit new.
    etwa so

    int main(void) {
    
        AllgemeinesGeraet *p_TestGeraet = new Kaffeemaschine("bla", 1);
    
        p_geraet1->GeraetEintragen(p_TestGeraet);
    
        p_TestGeraet->ausgabe();
    
    	return 0;
    }
    

    Kurt



  • jo das klingt logisch 🙂

    aber mir ist immer noch nicht klar wie ich diese Werte der Subklasse (zB: iAnzahlTassen) im überladenen << operator wieder auslesen kann. ich kann es ja nicht direkt ansprechen 😕.

    gruss quibb



  • quibb schrieb:

    aber mir ist immer noch nicht klar wie ich diese Werte der Subklasse (zB: iAnzahlTassen) im überladenen << operator wieder auslesen kann. ich kann es ja nicht direkt ansprechen 😕.

    Dein Beispiel macht auch nicht wirklich viel Sinn.
    Versuch mal das

    #include <vector>
    #include <string>
    #include <iostream>
    #include <sstream>
    using namespace std;
    
    class AllgemeinesGeraet {   
        protected:
    
            string sGeraetBezeichnung;
    
        public:
    
           AllgemeinesGeraet():sGeraetBezeichnung() { }
           AllgemeinesGeraet(string sBezeichnung) : sGeraetBezeichnung( sBezeichnung ) { ;}
           virtual ~AllgemeinesGeraet() { 
              cout << "deleting " << sGeraetBezeichnung << endl;
           }
    
           virtual string getBezeichnung() { return sGeraetBezeichnung; }
    
    };
    
    class Kaffeemaschine : public AllgemeinesGeraet {
    
        private:
    
            int iAnzahlTassen;
    
        public:
            virtual string getBezeichnung() { 
               stringstream str;
               str << sGeraetBezeichnung << " mit " << iAnzahlTassen << " Tassen";
                return str.str(); 
            }
    
            Kaffeemaschine(string sBezeichnung, int iTassen) :AllgemeinesGeraet(sBezeichnung), iAnzahlTassen( iTassen ) { ;}
    };
    
    int main() {
        vector<AllgemeinesGeraet*> Geraete;   
        Geraete.push_back( new AllgemeinesGeraet("Waschmaschine") );
        Geraete.push_back( new Kaffeemaschine("Espresso-Maschine", 6 ) );
    
        for ( vector<AllgemeinesGeraet*>::iterator i = Geraete.begin(); i != Geraete.end(); ++i )
           cout << (*i)->getBezeichnung() << endl;
    
        cout << "cleaning up " << endl;
    
        for ( vector<AllgemeinesGeraet*>::iterator i = Geraete.begin(); i != Geraete.end(); ++i )
           delete *i;
    
    }
    

    Kurt



  • ein ganzes programm, nice :). vielen dank, das werd ich mir jetzt mal genau anschauen.

    gruss quibb


Anmelden zum Antworten