Array von Klassen initialisieren



  • - (überflüssig) -



  • wie lautet denn die aktuelle fehlermeldung?
    der code, den du gepostet hast, sieht bis auf den typo mit include richtig aus. ich nehme an, du hast den vector kram in der main funktion? push_back kann natürlich, ebenso wie andere funktionen und methoden, nur in einer funktion oder methode aufgerufen werden.

    mithilfe von boost::assign kann man vectoren und andere standardkonforme container übrigens sehr elegant initialisieren:

    #include "Auto.h"
    
    #include <iostream>
    #include <vector>
    #include <boost/assign.hpp>
    using namespace std;
    using namespace boost::assign;
    
    int main()
    {
        vector<Auto> autos;
        autos += Auto(4, 6), Auto(0,2);
    
        cout << "Das erste Auto ist " << autos[0].zeigeAlter() << " Jahre alt.\n";
        cout << "Das zweite Auto hat " << autos[1].zeigeAnzahlSitze() << " Sitze." << endl;
    }
    


  • OK!

    Global war das Problem!

    Nun aber weiter - warum nur global?

    Ich nutze die Klasse in vielen Funktionen, die ich in der main.cpp habe, wie mach ich das dann? jedes mal als übergabeparameter den vektor übergeben?

    (aufgrund nicht mehr global hab ich jetzt natürlich errors: not deklared in this scope -> muss ich also wohl übergeben)



  • ah ok, jetzt ist mir klar warum push_back global nicht möglich ist - und dennoch, wie löse ich das am elegantesten, wenn ich in irgend einer funktion etwas von den autos brauche?

    sprich:

    void readout(/*hier vektor übergeben?*/)
    for(int i=0; i<o.size(); i++)
    {
       cout << o.radanzahl << endl
    }
    


  • Die Deklaration darf global sein, die Initialisierung der einzelnen Elemente (bzw. die Anhänge-Funktion push_back()) muss in einer Funktion stehen.
    Alternativ machst deklarierst du den Vektor auch lokal und übergibst ihn.

    std::vector autos;       // Deklaration global
    
    int main()
    {
       autos.push_back(...); // Anhängung von Elementen
       funktion();           // keine Übergabe erforderlich, da autos global ist
    }
    

    oder:

    int main()
    {
       std::vector autos;    // Deklaration lokal
       autos.push_back(...); // Anhängung von Elementen
       funktion(autos);      // Übergabe des Vektors als Parameter              
    }
    

    @ Simon2
    Da du natürlich die Beweismittel vernichtet hast, kann ich dich nicht mehr zitieren 😉
    Aber du hast geschrieben, der Kopierkonstruktor werde auch nicht mehr automatisch vom Compiler erstellt, wenn irgendein Konstruktor selber implementiert wurde. Das ist jedoch falsch. Er wird nur nicht mehr erstellt, wenn ein eigener Kopierkonstruktor vorhanden ist.
    Beim Standardkonstruktor gebe ich dir recht, ich war bis jetzt der Ansicht, das würde immer vom Compiler gemacht, wenn kein eigener implementiert war.

    Ich merke eben, ich kenne mich diesbezüglich zu wenig aus, weil ich für eine Klasse sowieso immer den Standardkonstruktor selber schreibe (nur schon damit die Membervariable nicht irgendwelche Werte annehmen).



  • puh, gut dass es global geht, ansonsten wäre das für mich ein weltuntergang gewesen. Danke!

    ich glaube somit war's das!

    Danke vielvielmals!

    Damit werd ich mich auch hier im Forum registrieren, super board, gut, dass man auch ohne Anmelden posten kann, jetzt bin ich überzeugt.

    Danke!

    By the way:

    Was ist boost? was kann man damit alles machen?



  • global ist hässlich. du könntest stattdessen eine garage bauen:

    #include <iostream>
    #include <vector>
    #include <boost/assign.hpp>
    using namespace std;
    using namespace boost::assign;
    
    //Auto
    
    class Auto
    {
    public:
    	Auto(size_t alter, size_t anzSitze);
    
        size_t zeigeAlter() const;
        size_t zeigeAnzahlSitze() const;
    
    private:
        size_t m_alter, m_anzSitze;
    };
    
    //Auto Implementierung
    
    Auto::Auto(size_t alter, size_t anzSitze)
    : m_alter(alter), m_anzSitze(anzSitze)
    {
    }
    
    size_t Auto::zeigeAlter() const
    {
        return m_alter;
    }
    
    size_t Auto::zeigeAnzahlSitze() const
    {
        return m_anzSitze;
    }
    
    //Garage
    
    class Garage
    {
    public:
    	static Garage &Aufmachen();
    
        const Auto &zeigeAuto(size_t position) const;
    
    private:
    	Garage();
    
    	vector<Auto> m_autos;
    };
    
    //Garage Implementierung
    
    Garage::Garage()
    {
        m_autos += Auto(4, 6), Auto(0,2); //eventuell mehr Autos in die Garage tun
    }
    
    Garage &Garage::Aufmachen()
    {
        static Garage g;
        return g;
    }
    
    const Auto &Garage::zeigeAuto(size_t position) const
    {
        return m_autos[position];
    }
    
    //Funktionen die Autos aus der Garage brauchen
    
    void foo()
    {
        cout << "Das erste Auto ist "
            << Garage::Aufmachen().zeigeAuto(0).zeigeAlter()
            << " Jahre alt.\n";
    }
    
    void bar()
    {
        Garage &g = Garage::Aufmachen();
    
        cout << "Das zweite Auto hat "
            << g.zeigeAuto(1).zeigeAnzahlSitze()
            << " Sitze." << endl;
    }
    
    //Hauptteil
    
    int main()
    {
        foo();
        bar();
    }
    

    boost hat sehr viele und sehr gute ergänzungen zu den c++ bibliotheken. es ist kostenlos und wird von unternehmen wie adobe verwendet. die meisten sachen aus boost kann man direkt verwenden, indem man sie inkludiert.



  • Autonom schrieb:

    By the way:
    Was ist boost? was kann man damit alles machen?

    Boost ist eine mächtige C++ Bibliothekssammlung (ich vermeide absichtlich die einzahl), die frei erhältlich ist. In der Regel braucht man nicht alles von Boost, sondern wählt aus einzelnen Bibliotheken das für sich sinnvolle aus.

    Ich würde sagen Boost ist nach der C++Standardbibliothek die zweit wichtigste C++ Bibliothek(-ssammlung). Die Boostautoren sitzen teilweise auch in Standardkomitee und Teile von Boost werden auch in den kommenden C++ Standard (C++0x) übernommen.

    Je nach Compiler gibt es ggf. installierbare Packete (so für MSVC 2003 und 2005 wenn ich mich nicht irre), ansonsten bitte die Anleitung beachten. Wobei das linken nicht bei allen Bibliotheken nötig ist (so sind z.B. die Smartpointer eine reine Header-Bibliothek).

    cu André



  • achso, ich hätte vllt noch dazu schreiben sollen, dass mit Garage::Aufmachen immer auf ein und die selbe garage zugegriffen wird. dies funktioniert gemäß des entwurfsmusters singleton. man braucht also keine angst zu haben, dass die garage mitsamt den autos bei jedem zugriff erstellt wird, denn dies passiert nur beim ersten mal und anschließend wird lediglich der zugriff auf die vorhandene garage geöffnet. wenn man nicht möchte, dass die garage die ganze zeit da (im speicher) ist, kann man dies wie folgt tun:

    //Garage
    
    class Garage
    {
    public:
    	static Garage &Aufmachen();
    
    	//wenn die Garage nicht mehr benötigt wird,
    	//kann hiermit der Spiecher freigegeben werden
    	static void Abreissen();
    
        const Auto &zeigeAuto(size_t position) const;
    
    private:
    	Garage();
    
    	//der Kopierkonstruktor sollte auch geschützt werden,
    	//um zuweisungen zu verhindern
    	Garage(const Garage &g){} 
    
    	vector<Auto> m_autos;
    
    	//statischer Zeiger auf die einzige Garage
    	static Garage *m_dieGarage;
    };
    
    //Garage Implementierung
    
    Garage *Garage::m_dieGarage = 0;
    
    Garage::Garage()
    {
        m_autos += Auto(4, 6), Auto(0,2); //eventuell mehr Autos in die Garage tun
    }
    
    Garage &Garage::Aufmachen()
    {
        if (m_dieGarage == 0)
            m_dieGarage = new Garage;
        return *m_dieGarage;
    }
    
    void Garage::Abreissen()
    {
        delete m_dieGarage;
        m_dieGarage = 0;
    }
    
    const Auto &Garage::zeigeAuto(size_t position) const
    {
        return m_autos[position];
    }
    


  • Hi, sorry das ich das nocheinmal aufrolle. Aber das Beispiel und die erklärung von velo sind spitze 🙂

    ich versuche mir aus lerngründe soviele Beispiele wie möchlich, um das Thema vectoren zusammen zu holen.

    Jetzt hätte ich beim Beispiel von | velo | versucht, Dynamisch das vector array zu erweitern, bin aber leider noch gescheitert.
    Im testfall sollte im main nach dem aufruf von foo und bar - mit einem pushback ein weiteres Element hinzugefügt werden das danach wieder ausgegen werden sollt.

    Frage ist das so überhaupt möglich?
    Könnte mir sonst evtl jemand einen Tipp geben, würde es gerne weiter probieren, sofern überhaupt möglich.

    Danke


  • Mod

    1. Werd konkret: Was ist dein Code? Was hast du gemacht? Was ist passiert? Was hast du stattdessen erwartet?
    2. Es ist recht unhöflich, derart alte Threads hervorzukramen. Ein Leser der das nicht sieht, liest nun erst drei Seiten, die eigentlich gar nichts zu deiner Frage zu tun haben, denn deine Frage ist ziemlich unabhängig vom bisherigen Inhalt des Threads und hätte auch eigenständig gestellt werden können.



  • SeppJ schrieb:

    1. Werd konkret: Was ist dein Code? Was hast du gemacht? Was ist passiert? Was hast du stattdessen erwartet?
    2. Es ist recht unhöflich, derart alte Threads hervorzukramen. Ein Leser der das nicht sieht, liest nun erst drei Seiten, die eigentlich gar nichts zu deiner Frage zu tun haben, denn deine Frage ist ziemlich unabhängig vom bisherigen Inhalt des Threads und hätte auch eigenständig gestellt werden können.

    Hallo, ich meine den Code den _ Velo _ hier gepostet hat:
    Was ein super Beispiel ist - jedoch ist der vector ccontainer "statisch" und ich versuche mich daran den code so abzuändern damit man auch vom - Main - aus werte hinzufügen kann, bzw. vector function benutzen kann.

    Dazu müsste der geschlossene vektor erst geöffnet werden und dann über eine womöglich weitere classe zugegriffen werden. - Ich habe es heute noch etwas probiert aber, aber hinbekommen tu ich es nicht.

    einfach in die Classe Garage eine Funktion beifügen mit Übergabeparameter vom Main, funktioniert ja nicht, da Garage Aufmachen ja auf Garage::Garage() verweist.

    Die Vector Initialisierung "vector<Auto> m_autos;" sollte aber weiterhin bewusst private bleiben. Oder ist es so dann nicht möglich?
    BZw. auch wenn sie public wird, müsste dann das abfragen der Daten geändert werden, nur wie - darauf bin ich noch nicht gekommen.

    #include <iostream> 
    #include <vector> 
    #include <boost/assign.hpp> 
    using namespace std; 
    using namespace boost::assign; 
    
    //Auto 
    
    class Auto 
    { 
    public: 
        Auto(size_t alter, size_t anzSitze); 
    
        size_t zeigeAlter() const; 
        size_t zeigeAnzahlSitze() const; 
    
    private: 
        size_t m_alter, m_anzSitze; 
    }; 
    
    //Auto Implementierung 
    
    Auto::Auto(size_t alter, size_t anzSitze) 
    : m_alter(alter), m_anzSitze(anzSitze) 
    { 
    } 
    
    size_t Auto::zeigeAlter() const 
    { 
        return m_alter; 
    } 
    
    size_t Auto::zeigeAnzahlSitze() const 
    { 
        return m_anzSitze; 
    } 
    
    //Garage 
    
    class Garage 
    { 
    public: 
        static Garage &Aufmachen(); 
    
        const Auto &zeigeAuto(size_t position) const; 
    
    private: 
        Garage(); 
    
        vector<Auto> m_autos; 
    }; 
    
    //Garage Implementierung 
    
    Garage::Garage() 
    { 
        m_autos += Auto(4, 6), Auto(0,2); //eventuell mehr Autos in die Garage tun 
    } 
    
    Garage &Garage::Aufmachen() 
    { 
        static Garage g; 
        return g; 
    } 
    
    const Auto &Garage::zeigeAuto(size_t position) const 
    { 
        return m_autos[position]; 
    } 
    
    //Funktionen die Autos aus der Garage brauchen 
    
    void foo() 
    { 
        cout << "Das erste Auto ist " 
            << Garage::Aufmachen().zeigeAuto(0).zeigeAlter() 
            << " Jahre alt.\n"; 
    } 
    
    void bar() 
    { 
        Garage &g = Garage::Aufmachen(); 
    
        cout << "Das zweite Auto hat " 
            << g.zeigeAuto(1).zeigeAnzahlSitze() 
            << " Sitze." << endl; 
    } 
    
    //Hauptteil 
    
    int main() 
    { 
        foo(); 
        bar(); 
    
    }
    


  • Ich verstehe nicht, was du mit geschlossenem Vektor meinst.

    Aber du kannst aus der main() natürlich nicht direkt auf private Member der Klasse Garage zugreifen. Du kannst sowas versuchen:

    void Garage::addCar(const Auto& myCar){
       m_autos.push_back(myCar)
    }
    

    und dann in der Main

    Garage &g = Garage::Aufmachen();
     g.addCar(Auto(1,3));
    


  • marigold schrieb:

    Aber das Beispiel und die erklärung von velo sind spitze 🙂

    OT, aber wie man auf die Idee kommen kann, das ausgerechnet eine Garage ein Singleton sein soll, ist mir schleierhaft.
    Und das Zugreifen auf die weltweit einzige Garage auch noch 'Aufmachen' zu nennen, würde ich dann nicht als 'spitze' bezeichnen.



  • Das funktioniert 👍 - Danke vielmals -
    Okay so könnte man dann weitere Vector Funktionen deklarieren und abrufen.
    muss ich dann noch ausprobieren.

    @Jockelx - ich bin noch grün hinter den Ohren, was das betrifft - für mich ist es daher ein gutes Beispiel. Wie würdest du es machen, oder was könntest du empfehlen?



  • Üblicherweise einfach

    Garage g;
    g.addCar(Auto(1,3));
    

Anmelden zum Antworten