[SOLVED] Variablen Zugriff via Vektoren Liste



  • Guten Abend Liebe Community,

    ich habe einen List Container erstellt in welchem mehrere Objekte gespeichert werden. Am Ende sollen die Objekte ausgegeben werden.

    Dies klappt auch wunderbar bis auf den Punkt, dass die Ausgabe nur public Variablen lesen kann, auf private Variablen bekomme ich den Fehler, dass er nicht darauf zugreifen kann, weil die Variablen private sind.

    Ich kann mir den Fehler gerade selber nicht erklären, da die Liste ja vom Typ der Klasse ist und damit doch auch Zugriff auf die Variablen haben muss.

    Könntet ihr meinen Denkfehler vllt beheben? 🙂

    #include <iostream>
    #include <string>
    #include <iterator>
    #include <list>
    
    using namespace std;
    
    class CPerson {
          public:
                 CPerson(string, string, int); 
                 void Eingabe();
          private:
                 int GebJahr;
                 string Name;
                 string Ort; 
    
    };
    CPerson::CPerson(string pName, string pOrt, int pJahr) //Standardkonstruktor
    {
           Name = pName;
           Ort = pOrt;
           GebJahr = pJahr; 
    
    }
    
    int main() 
    {
       list<CPerson> VListe; //Container Erstellung
    
       CPerson Objekt_1("Hans","Frankfurt",1986);  // Objekt Erstellung 1
       CPerson Objekt_2("Lenny","Wiesbaden",2009); // Objekt Erstellung 2
       CPerson Objekt_3("Max","Buchter",2222);     // Objekt Erstellung 3
    
       VListe.push_back(Objekt_1); // Objekt in den Container packen
       VListe.push_back(Objekt_2); // Objekt in den Container packen
       VListe.push_back(Objekt_3); // Objekt in den Container packen
    
       list<CPerson>::iterator pos; // Iterator definieren
    
       // Ausgabe des Containers via Iterator
        for (pos = VListe.begin(); pos != VListe.end(); pos++) {
               cout << pos->Name << " - ";
               cout << pos->Ort << " - ";
               cout << pos->GebJahr << endl;
    
        } 
        getchar();        
    }
    

    Grüße -- Kaiten



  • Du kannst die Instanzen nicht einfach so aufrufen. Wie du richtig erkannt hast sind diese als private deklariert und somit hast du keine Zugriffsberechtigungen. Entweder du machst sie public oder du schreibst einen Getter. Ansonsten nehme ich für sowas auch gerne Strukturen.



  • Hallo Kóyaánasqatsi,

    erstmal danke für deine Antwort.
    Ich weiss nicht ob ich gerade auf dem Schlauch stehe oder nicht. Der List Container ist von der Klasse CPerson. Müsste nicht dieser wie bei einer Objekterstellung der Klasse CPerson auf alle Elemente zugreifen können? Oder gibt das list<CPerson> nur an, dass nur Objekte der Klasse CPerson gespeichert werden könenn aber dies nichts mit dem Zugriff zu tun hat ?



  • Oder gibt das list<CPerson> nur an, dass nur Objekte der Klasse CPerson gespeichert werden könenn aber dies nichts mit dem Zugriff zu tun hat ?

    richtig

    du brauchst also:
    Getter / Setter

    was du auch noch angucken könntest:
    Initialisierungsliste
    call by (const) reference

    bb



  • Kaiten schrieb:

    Oder gibt das list<CPerson> nur an, dass nur Objekte der Klasse CPerson gespeichert werden könenn aber dies nichts mit dem Zugriff zu tun hat ?

    Genau. std::list weiss überhaupt nichts, was CPerson anbelangt (das kann, soll es auch nicht können).



  • Ah okay.

    Vielen Dank an euch alle! 🙂
    Ich probier mich dann mal an euren Lösungen.

    Grüße



  • Es hat nun geklappt, ich poste nur den richtigen Code 🙂

    #include <iostream>
    #include <string>
    #include <iterator>
    #include <list>
    
    using namespace std;
    
    class CPerson {
          public:
                 CPerson(string, string, int); 
                 void Eingabe();
                 int getJahr() {return GebJahr;}
                 string getName(){ return Name;}
                 string getOrt(){return Ort;}
          private:
                 int GebJahr;
                 string Name;
                 string Ort; 
    
    };
    CPerson::CPerson(string pName, string pOrt, int pJahr) //Standardkonstruktor
    {
           Name = pName;
           Ort = pOrt;
           GebJahr = pJahr; 
    
    }
    
    int main() 
    {
       list<CPerson> VListe; //Container Erstellung
       CPerson Objekt_1("Hans","Frankfurt",1986);  // Objekt Erstellung 1
       CPerson Objekt_2("Lenny","Wiesbaden",2009); // Objekt Erstellung 2
       CPerson Objekt_3("Max","Buchter",2222);     // Objekt Erstellung 3
    
       VListe.push_back(Objekt_1); // Objekt in den Container packen
       VListe.push_back(Objekt_2); // Objekt in den Container packen
       VListe.push_back(Objekt_3); // Objekt in den Container packen
    
       list<CPerson>::iterator pos; // Iterator definieren
    
       // Ausgabe des Containers via Iterator
        for (pos = VListe.begin(); pos != VListe.end(); pos++) {
               cout << pos->getName() << " - ";
               cout << pos->getOrt() << " - ";
               cout << pos->getJahr() << endl;
        } 
        getchar();        
    }
    

    Grüße



  • #include <iterator>
    brauchst du nicht

    CPerson Objekt_1("Hans","Frankfurt",1986);  // Objekt Erstellung 1 
       CPerson Objekt_2("Lenny","Wiesbaden",2009); // Objekt Erstellung 2 
       CPerson Objekt_3("Max","Buchter",2222);     // Objekt Erstellung 3 
    
       VListe.push_back(Objekt_1); // Objekt in den Container packen 
       VListe.push_back(Objekt_2); // Objekt in den Container packen 
       VListe.push_back(Objekt_3); // Objekt in den Container packen
    

    ist ein wenig umständlich...

    paar kommentare:

    /*x-header*/
    #include <string> 
    
    //hier könnte man noch mal nach call by reference googlen
    class CPerson { 
          public: 
                 CPerson(string, string, int); //hier unbedingt namen angeben, weil keiner gerne in der implementierungs-datei nachguckt, um rauszubekommen, was er übergeben muss
                 void Eingabe(); //komischer name
                 int getJahr() /*const*/ {return GebJahr;} 
                 std::string getName() /*const*/ { return Name;} 
                 std::string getOrt() /*const*/ {return Ort;} 
          private: 
                 int GebJahr; 
                 std::string Name; 
                 std::string Ort; 
    };
    
    /*x-source*/
    #include "x-header"
    
    using namespace std;
    
    CPerson::CPerson(string pName, string pOrt, int pJahr) 
    { 
           Name = pName; 
           Ort = pOrt; 
           GebJahr = pJahr; 
    
    }
    //hierzu könnte man noch mal nach "Initialisierungsliste" googlen
    
    /*main*/
    
    #include <iostream> 
    #include <list> 
    using namespace std; 
    
    #include "x-header"
    
    int main() 
    { 
       list<CPerson> VListe;
    
       VListe.push_back(CPerson("Hans","Frankfurt",1986));
       VListe.push_back(CPerson("Lenny","Wiesbaden",2009));
       VListe.push_back(CPerson("Max","Buchter",2222));
    
       for(list<CPerson>::const_iterator pos(VListe.begin()); pos != VListe.end(); ++pos)
       {
          cout << pos->getName() << " - "
             << pos->getOrt() << " - "
             << pos->getJahr() << endl; 
       }
    
       getchar();         
    }
    

    bb

    PS: Standardkonstruktor ist der CTor, der keine Parameter erwartet - den, der bei deinem Objekt (zu recht) nicht existiert...



  • Ich darf noch anmerken:

    /*x-header*/
    #include <string>
    
    class CPerson {
          //hier könnte man noch mal nach call by reference googlen
          public:
                 /* explicit */CPerson(string, string, int); // explizit verhindert ungewollte (seltsame) Typkonvertierung
                 void Eingabe(); //komischer name
                 int getJahr() /*const*/ {return GebJahr;}
                 std::string getName() /*const*/ { return Name;}
                 std::string getOrt() /*const*/ {return Ort;}
          private:
                 int GebJahr;
                 std::string Name;
                 std::string Ort;
    };
    

    Grüssle DC



  • zu explicit: aber nur, wenn die Parameter Standard-Belegungen hätten:

    struct T {}; //member-klasse - man könnte auch jeden anderen typen nehmen - aber so ists übersichtlicher, find ich
    
    struct X //alle bsp mal in einem struct - sonst wird das zu viel tipparbeit ;P
    {
      /*explicit*/ X(T m);
      /*explicit*/ X(T m = T());
      /*explicit*/ X(T m, T m2 = T());
      /*        */ X(T m, T m2);
      /*        */ X(T m, T m2, T m3 = T());
      /*        */ X(T m, T m2, T m3);
    };
    

    Also ab dem Zeitpunkt, wo der CTor 2 Parameter erwartet, muss man sich da keine Gedanken mehr machen...

    bb



  • unskilled schrieb:

    Also ab dem Zeitpunkt, wo der CTor 2 Parameter erwartet, muss man sich da keine Gedanken mehr machen...

    Ich sehe das explicit c_tor Konzept eher als Richtlinie, lieber mal ein explicit mehr geschrieben als zu wenig, so kommt man dann seinen eigenen Fehlern besser auf die Schliche.

    Ansonsten Danke für Tipp! 👍



  • DeepCopy schrieb:

    Ich sehe das explicit c_tor Konzept eher als Richtlinie, lieber mal ein explicit mehr geschrieben als zu wenig, so kommt man dann seinen eigenen Fehlern besser auf die Schliche.

    Ja, würde ich auch meinen. Eigentlich spräche auch gar nichts dagegen, Konstruktoren automatisch als explicit zu kennzeichnen und diese Kennzeichnung erst zu entfernen, wenn man implizite Konvertierung wirklich braucht. Soviel ich weiss, ist es nämlich nur aus Kompatibilitätsgrunden nicht so, dass etwas wie implicit existiert (und Konstruktoren standardmässig explizit sind) - in meinen Augen ist implizite Konvertierung nämlich eher der Ausnahmefall, der speziell markiert werden sollte.


Anmelden zum Antworten