c++ dynamische Strukturen



  • Hey, ich komme ja gar nicht mehr mit dem Lesen und Nachvollziehen hinterher 🙂
    Vielen vielen Dank. Mit Klassen kenne ich mich eigentlich schon aus.
    Ich werde jetzt zuerst einmal versuchen alles zu verstehen und nach zu programmieren. Ihr seid wirklich spitze.



  • Gern geschehen. Dann viel Erfolg - und bei Fragen kannst du dich natürlich jederzeit hier melden...



  • #include <iostream> 
    #include <vector> 
    #include <string>
    using namespace std; 
    
    //--------------------------------------------------------------
    //--------------------------------------------------------------
    class PersonenListe 
    { 
    public: 
            string GetName(); 
            PersonenListe :: PersonenListe(string n); 
    private: 
            string Name; 
    }; 
    vector<PersonenListe>Personen; 
    PersonenListe :: PersonenListe(string n) : Name(n) 
    { 
    } 
    void hinzufügenPerson( string n ) 
    { 
            Personen.push_back(  PersonenListe(n) ); // Die Daten (string n) werden mithilfe des Konstruktors PersonenListe :: PersonenListe(string n); 
    }                                               // in den Vector Personen gepusht 
    string PersonenListe :: GetName() 
    { 
            return Name; 
    } 
    //--------------------------------------------------------------
    //--------------------------------------------------------------
    class Gruppenliste
    { 
    public: 
            string GetGroupname();
            Gruppenliste::Gruppenliste(string name); 
    		vector<PersonenListe>Personen;
    private: 
            string GName; 
    }; 
    vector<Gruppenliste>Gruppen; 
    Gruppenliste :: Gruppenliste(string name): GName(name)
    { 
    } 
    void hinzufügenGruppe( string name ) 
    { 
            Gruppen.push_back(  Gruppenliste(name) ); // Die Daten (string n) werden mithilfe des Konstruktors PersonenListe :: PersonenListe(string n); 
    }                                              // in den Vector Personen gepusht 
    string Gruppenliste :: GetGroupname() 
    { 
            return GName; 
    } 
    //main-------------------------------------------------------------
    int main() 
    { 
    hinzufügenGruppe("GruppeA"); 
    hinzufügenGruppe("GruppeF"); 
    hinzufügenGruppe("GruppeU"); 
    
    for (int i=0; i<=Gruppen.size()-1; i++)
    	cout<<Gruppen[i].GetGroupname()<<endl;
    
    Gruppen[0].Personen.hinzufügenPerson("Andrea"); // <- Hier ist der Wurm drin :(
    
    cout<<endl;
    system("PAUSE");
    return 0; 
    }
    

    Hey ihr, wie ihr sehen könnt war ich fleißig. Ich habe hierbei aber jetzt noch das Problem, dass ich in der einzelnen Gruppe keine Personen anlegen kann. Ich weiß aber nicht, was ich falsch mache 😞

    /edit pumuckl: cpp-Tags spendiert. Demnächst bitte selber machen! 😉



  • Hallo Melli,

    als erstes solltest du cpp-Tags verwenden, wenn du hier Code postest, weil das sonst nicht gut lesbar ist. Dann ist "hier ist der Wurm drin" keine gute Fehlerbeschriebung. Was passiert? Was sollte deiner Meinung nach passieren? Welche Fehlermeldung kommt vom Compiler?

    Dann bist du mit deinen Klassen irgenwie durcheinandergekommen. Du hast eine Klasse "Gruppenliste". Wofür benötigst du die? Ich glaube, du hast den Code von Bassmaster nicht richtig verstanden.

    Ich gebe dir mal ein wenig Struktur:

    class Person
    {
      public:
        explicit Person(const std::string& name) : m_name(name) {}
    
        const std::string& GetName() const {return m_name;};
    
      private:
        std::string m_name;
    };
    
    class Gruppe
    {
      public:
        explicit Gruppe(const std::string& name) : m_name(name) {}
    
        const std::string& GetName() const {return m_name;};
        void AddPerson(const Person& person) {m_personen.push_back(person);};
    
      private:
        std::string m_name;
        std::vector<Person> m_personen;
    };
    
    int main()
    {
      std::vector<Gruppe> gruppen;
    
      gruppen.push_back(Gruppe("Frauen"));
      gruppen.push_back(Gruppe("Maenner"));
    
      gruppen[0].AddPerson(Person("Andrea"));
      gruppen[0].AddPerson(Person("Melli"));
    
      gruppen[1].AddPerson(Person("Thomas"));
      gruppen[1].AddPerson(Person("Felix"));
    
      return 0;
    }
    


  • 😮 Dein Quellcode und die Bezeichner sind total verwirrend.

    Melanie_27 schrieb:

    class PersonenListe 
    { 
    public: 
            string GetName(); 
            PersonenListe(string n); 
    private: 
            string Name; 
    };
    // ...
    Gruppen[0].Personen.hinzufügenPerson("Andrea");
    

    Wieso hat die Liste einen Namen. Eine Person soll einen Namen haben, aber die Liste doch nicht.

    Melanie_27 schrieb:

    void hinzufügenGruppe( string name )
    {
        Gruppen.push_back( Gruppenliste(name) );
    }
    // ...
    hinzufügenGruppe("GruppeA"); 
    hinzufügenGruppe("GruppeF"); 
    hinzufügenGruppe("GruppeU");
    

    Das ist doch redundant. std::vector hat doch bereits so eine Funktion. Außerdem hast du mit dieser Methode nun eine globale Variable Gruppen an der Backe.



  • Ahhh, ich bin so dumm 😞 😞 😞
    Ich sitz jetzt gerade an dem Code von Felix und bin zumindest mal in der Lage Gruppen und darin Personen anzulegen 🙂

    for(int i=0; i<=gruppen.size()-1; i++)
      {
    	  cout<<gruppen[i].GetName()<<endl;           //Das funktioniert bestens
      }
    
      for(int i=0; i<=gruppen[0].m_personen.size()-1; i++)    //Das kennt er nicht
      {                                                       //weil m_personen privat ist
    	  cout<<gruppen[0].m_personen[i].GetName()<<endl;  //Das folglich auch nicht.
      }
    

    Aber wie kann ich jetzt die Personen wieder auslesen? m_personen ist private. Wie kann ich die Größe des Personen-Vektors bestimmen und wie kann ich seinen Namen auslesen?
    O man, ihr lacht mich bestimmt schon aus 😞
    Ich danke euch.



  • Denk doch mal objektorientiert 😉

    void Gruppe::Print() const
    {
      cout << "Gruppe '" << m_name << "':\n";
    
      // hier kommt die Ausgabe des vectors
    }
    


  • Ok, ich hab es einfach public gemacht und es funktioniert :)) Ansonsten hätte ich wohl eine Methode schreiben müssen, die mir m_person ausspuckt 🙂
    Hab ich Recht oder nicht ? :)))



  • Sowas durch "public-machen" zu lösen ist nicht sonderlich schön, es wiederspricht fundamental dem Konzept der Kapselung von Daten. Eine Lösung habe ich ja bereits zeitgleich mit dir gepostet.

    Angenommen, du möchtest irgendwann den vector durch eine andere Struktur ersetzen, dann genügt es, wenn du die "Print()"-Methode änderst. Wenn du einfach den vector public machst, musst du in mühsamer Kleinarbeit alle Stellen im Code ändern, wo du darauf zugreifst.



  • Hääh? Aber das was du gepostet hast, hat doch nichts mit m_personen zu tun? Ich möchte ja die Personen ausgeben, die eine Gruppe hat.
    Wie geht das dann, wenn ich std::vector<Person> m_personen; in der Klasse Gruppe bei private stehen hab???



  • Melanie_27 schrieb:

    Hääh? Aber das was du gepostet hast, hat doch nichts mit m_personen zu tun? Ich möchte ja die Personen ausgeben, die eine Gruppe hat.
    Wie geht das dann, wenn ich std::vector<Person> m_personen; in der Klasse Gruppe bei private stehen hab???

    Hast Du den Kommentar in felix' Code überlesen? 😉

    Wenn Du die Personen in einer Gruppe ausgeben möchtest, kannst Du doch eine Funktion "Ausgabe" in der Klasse Gruppe schreiben, die über den privaten Vector m_personen iteriert.

    Oder Du bietest in der Klasse Gruppe eine Get-Methode für eine bestimmte Person (nach Index) oder den gesamten Vector an, und nutzt diese statt des privaten m_personen.



  • [offtopic]
    Kaum ist ein Benutzername weiblich wird hier mit Code umsich geschmissen, wäre er männlich gewesen gäbe es mit sicherheiten schon die ein oder andere Moralpredigt 😃
    [/offtopic]



  • Cyres schrieb:

    [offtopic]
    Kaum ist ein Benutzername weiblich wird hier mit Code umsich geschmissen, wäre er männlich gewesen gäbe es mit sicherheiten schon die ein oder andere Moralpredigt 😃
    [/offtopic]

    nein, ich zumindest bin immer meistens freundlich 🕶



  • Ok, das habe ich jetzt verstanden. Ich habe ja auch gemeint, dass ich eine Methode schreibe, die den Vector Personen m_personen zurück gibt:
    Ich habe diese Methode jetzt geschrieben, aber irgendwie mag mich mein Visual Studio nicht 😞

    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    class Person 
    { 
      public: 
        explicit Person(const std::string& name) : m_name(name) {} 
        const std::string& GetName() const {return m_name;}; 
    
      private: 
        std::string m_name; 
    }; 
    //------------------------------------------------------------------------
    class Gruppe 
    { 
      public: 
        explicit Gruppe(const std::string& name) : m_name(name) {} 
        const std::string& GetName() const {return m_name;}; 
        void AddPerson(const Person& person) {m_personen.push_back(person);};
    	vector<Person> getPerson () {return m_personen;}
    
      private: 
        std::string m_name; 
        std::vector<Person> m_personen;
    }; 
    //-------------------------------------------------------------------------
    int main() 
    { 
      std::vector<Gruppe> gruppen; 
    
      gruppen.push_back(Gruppe("Frauen")); 
      gruppen.push_back(Gruppe("Maenner")); 
    
      gruppen[0].AddPerson(Person("Andrea")); 
      gruppen[0].AddPerson(Person("Melli")); 
    
      gruppen[1].AddPerson(Person("Thomas")); 
      gruppen[1].AddPerson(Person("Felix")); 
    
      for (int i=0; i<=gruppen.size(); i++)
      {
    		cout<<gruppen[i].GetName()<<":"<<endl;   
    	for(int a=0; a<=gruppen[i].getPerson.size(); a++)    //Das kennt er nicht
    	{       
    		 cout<<gruppen[i].getPerson[a].GetName()<<endl;  //Das folglich auch nicht.
    	}
      }
      cout<<endl;
      system("PAUSE");
      return 0; 
    }
    

    Und ich bin sehr froh, dass es Leute wie euch/dich :p gibt, die mir helfen.



  • Dann schau mal, wie du die Methode GetName (die keine Parameter hat) aufrufst: GetName(). Und jetzt überleg, wie Du die Methode GetPerson (die auch keine Parameter hat) aufrufen müsstest 😉



  • und achte bei der Benennung deiner Methoden auf konsistenz. Einmal hast du "GetName()" und einmal "getPerson()", entweder fang alles mit einem großen Buchstaben an oder alles mit einem kleinen.



  • Ich schau es mir gerade wieder und wieder an, aber ich versteh den Fehler einfach nicht. Ich möchte m_personen zurückgeben. Irgendwie scheint das nicht zu funktionieren, aber warum?



  • du solltest besser eine konstante Referenz zurückgeben, sonst wird jedesmal eine Kopie erzeugt. Der Name "getPerson" ist auch ungünstig, wenn du nciht eine einzelne Person, sondern eine ganze Liste haben möchtest 😉

    const std::vector<Person>& GetPersonen() const {return m_personen;};
    

    und anstelle von "mag nicht" wäre es hilfreich, wenn du uns die tatsächliche Fehlermeldung geben könntest...



  • Keine Chance, läuft trotzdem nicht. Es kommt die Fehlermeldung:

    Fehler 2 error C2228: Links von ".size" muss sich eine Klasse/Struktur/Union befinden. m:\visual studio 2010\projects\einfacheliste\einfacheliste\main.cpp 45

    6 IntelliSense: Ein Zeiger auf eine gebundene Funktion darf nur zum Aufrufen der Funktion verwendet werden. m:\visual studio 2010\projects\einfacheliste\einfacheliste\main.cpp 45

    Hier nochmal der komplette Code:

    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    class Person 
    { 
      public: 
        explicit Person(const std::string& name) : m_name(name) {} 
        const std::string& GetName() const {return m_name;}; 
    
      private: 
        std::string m_name; 
    }; 
    //------------------------------------------------------------------------
    class Gruppe 
    { 
      public: 
        explicit Gruppe(const std::string& name) : m_name(name) {} 
        const std::string& GetName() const {return m_name;}; 
        void AddPerson(const Person& person) {m_personen.push_back(person);};
    	const std::vector<Person>& getPersonen () const {return m_personen;};
    
      private: 
        std::string m_name; 
        std::vector<Person> m_personen;
    }; 
    //-------------------------------------------------------------------------
    int main() 
    { 
      std::vector<Gruppe> gruppen; 
    
      gruppen.push_back(Gruppe("Frauen")); 
      gruppen.push_back(Gruppe("Maenner")); 
    
      gruppen[0].AddPerson(Person("Andrea")); 
      gruppen[0].AddPerson(Person("Melli")); 
    
      gruppen[1].AddPerson(Person("Thomas")); 
      gruppen[1].AddPerson(Person("Felix")); 
    
      for (int i=0; i<=gruppen.size(); i++)
      {
    		cout<<gruppen[i].GetName()<<":"<<endl;   
    	for(int a=0; a<=gruppen[i].getPersonen.size(); a++)    //Das kennt er nicht
    	{       
    		 cout<<gruppen[i].getPersonen[a].GetName()<<endl;  //Das folglich auch nicht.
    	}
      }
      cout<<endl;
      system("PAUSE");
      return 0; 
    }
    

    Es scheint noch immer an getPersonen zu liegen 😞



  • Melanie_27 schrieb:

    for(int a=0; a<=gruppen[i].getPersonen.size(); a++)    //Das kennt er nicht
    	{       
    		 cout<<gruppen[i].getPersonen[a].GetName()<<endl;  //Das folglich auch nicht.
    	}
      }
    

    mit gruppen[i].getPersonen rufst du auch keine Methode auf.
    Lies dir nochmal den letzten Kommentar von LordJaxom genau durch.


Anmelden zum Antworten