Struct



  • wie ein vector arbeitet is wohl klar

    vector<int> data(4, 2);
    
    printf("data[0] value: %d\n",data.at(0));
    

    die frage ich nur wie ich das mit einem struct hinbekommen könnte, um später die einzelnen elemente des structs im vector ansprechen aber auch manipulieren zu können

    struct data
    {
        int param1;
        int param2;
    
        short ID;
    
        //.....
    };
    
    vector<data> data_storage;
    //.....?
    

  • Mod

    Du darfst Operationen auch gerne aneinander hängen. Der Rückgabewert von at (beziehungsweise dem Operator[]) ist ein data (oder genau genommen ein data&). Und auf dieses darfst du gerne den Elementzugriffsoperator '.' anwenden:
    data_storage[0].param1 = ...;



  • Ein fragälchen: wieso benutzt du printf?
    Und

    std::vector<data> bla(/*z.B.*/ 5, data());
    
    bla.at(0).param1 = 15;//oder
    bla.front().param1 = 15;
    
    //Die geben Referenzen auf die gelagerten Objekte zurück
    

    schau mal hier.

    Edit: const_reference und reference sind afaik typedefs in den Klassen



  • Hacker schrieb:

    Ein fragälchen: wieso benutzt du printf?

    Ich habe viel mit C programmiert und naja, die alten Angewohnheiten wie printf();
    sind geblieben und noch heute in Benutzung 🙂
    std::cout mag vielleicht besser sein aber ich habe bis jetzt noch keine wirklich entscheidenden Gründe gefunden es anstatt printf zu nutzen, vielleicht kannst du mir ja welche sagen? 🙂

    Also, ich hab jetzt ein bisschen rumprobiert und einen Konstruktor in meine Struktur eingebaut, endlich funktioniert es und sieht jetzt so aus:

    struct data
    {
       //beispiel attribut
       int param1
    
       //konstruktor
       data()
       {
          param1 = 0;
       }
    };
    
    int main()
    {
       int ammount = 6;
    
       vector<data> data_storage;
    
       for(int init = 0; init <= ammount; init++)
       {
          data_storage.push_back(data());
       }
    
       //...
    }
    

    wäre das soweit korrekt oder mache ich damit trotz Erfolgreicher Kompilation etwas falsch?



  • Tut mir leid, dich enttäuschen zu müssen, aber der Code ist schlichtweg nicht compilierbar. Du hast nämlich Semikolon in Zeile 4 vergessen.
    Spaß beiseite. Der Code sieht schon ok aus, aber du weißt schon, dass deine Schleife siebenmal durchlaufen wird, oder? Wenn bei ammount eine andere Zahl steht, kann das bei dem Einem oder Anderen ziemlich schnell zu Fehlern führen.


  • Mod

    Du machst da einige stilistische Fehler:
    Man schreibt gerne ++i. In C egal, aber in C++ kann i wer weiß was sein, wo das einen Unterschied macht. Hier weißt du zwar, dass es int ist, aber dann ist es konsistent zu deinen anderen Schleifen.
    Das Setzen eines Members im Konstruktor gehört nicht in den Konstruktor sondern in die Initialisierungsliste.
    Die ganze Schleifenkonstruktion kannst du dir sparen, indem du den passenden Konstruktor von vector benutzt.
    printf benutzt man nicht in C++, da es mit den höheren Sprachkonzepten in C++ nicht kompatibel ist. Gewöhn es dir daher möglichst bald ab.
    Gewöhn dir auch vieles andere aus C ab, es sind quasi zwei verschiedene Sprachen mit gleicher Syntax. Gerne werden von ehemaligen C-Programmierern z.B. malloc, Arrays (insb. char-Arrays), Pointe, Funktionen im Stil der C-Standardbibliothek (d.h. Fehlerbehandlung durch Rückgabewert) und Funktionen der C-Standardbibliothek für die es in C++ einen Ersatz gibt benutzt. Du benutzt schon vector, das sieht gut aus 👍 .



  • RussianTux schrieb:

    std::cout mag vielleicht besser sein aber ich habe bis jetzt noch keine wirklich entscheidenden Gründe gefunden es anstatt printf zu nutzen, vielleicht kannst du mir ja welche sagen? 🙂

    std::cout ist Typsicher.

    RussianTux schrieb:

    Also, ich hab jetzt ein bisschen rumprobiert und einen Konstruktor in meine Struktur eingebaut

    Eigentlich.. solltest du keinen (eigenen) Konstruktor brauchen.

    RussianTux schrieb:

    wäre das soweit korrekt oder mache ich damit trotz Erfolgreicher Kompilation etwas falsch?

    Na ja, initialisierung im Konstruktor erledigt man möglichst in der Initialisierungsliste. Das sieht dann so aus:

    struct A
    {
      int i;
      char c;
      A()
        : i(5), c('z')  // <-
      {}
    

    Edit: Und das was SeppJ sagt. Sieh dir z.B. den Code von Hacker an, der std::vector hat bereits einen fertigen Konstruktor für das was du in der Schleife machst.



  • Wieso cout statt printf? 😃

    template <class T>
    void printtwice(const T& e)
    {
    	if(typeid(T) == typeid(int))
    		std::printf("%i%i", e, e);
    	if(typeid(T) == typeid(double))
    		std::printf("%f%f", e, e);
    	//-...........
    }
    
    template <class T>
    void printtwice(const T& e)
    {
    	std::cout << e << e;
    }
    

    Oder ginge das mit printf auch anders?



  • Und operator << kann noch mehr (man glaubt es kaum), passt sogar zu deinem Eingangsposting:

    struct Point
    {
      float x, y, z;
      Point(float x_, float y_, float z_)
        : x(x_), y(y_), z(z_)
      {}
    };
    
    std::ostream &operator << (std::ostream &stream, const Point &point)
    {
      stream << "(x: " << point.x << " y: " << point.y << " z: " << point.z << ")";
      return stream;
    }
    
    int main()
    {
      Point point(4.534f, 7.46f, 23.46f);
      std::cout << point;
    }
    

    Edit:
    Was halt stört ist, dass man für jedes << einen Funktionsaufruf hat. Multithreading ist so quasi nicht möglich (man muss halt irgendwie manuell locken).



  • Überladung.



  • Danke euch für die vielen Antworten, es funktioniert soweit alles prächtig, nur bleibt noch eine Frage offen, wie sieht es mit 2 dimensionalen Vektoren aus? 😃

    wie man sie deklariert kann ich mir bisschen vorstellen, nur wie greife ich dann mit .at() auf die Elemente zu und wie lösche bzw. erstelle ich neue Container mittels .push_back() ?

    p.s. werde versuchen den C style nicht mehr zu benutzen und statt dessen die nativen C++ Bibliotheken nutzen



  • Auf verschachtelte Vektoren kannst du mit Iteratoren zugreifen.

    Zugriff:

    vector<vector<data> >::iterator itA;  //Iterator definieren
    for (itA = A.begin(); itA != A.end(); ++itA) {
      vector<data>::iterator itB;
      for (itB = itA->begin; itB != itA->end(); ++itB)
        itB->member1 = 4; //Hier kann dann auf die Member zugegriffen werden, etc.
    }
    

    EDIT:
    Deklaration wären dann z.B.:

    vector<vector<data> > A;
    for (int i=0; i<3; ++i) {
      vector<data> B;
      for (int j=0; j<3; ++j)
        B.push_back(data());
      A.push_back(B);
    }
    

    Ist nicht getestet, kann sein dass sich Fehler eingeschlichen haben 😉



  • mortified_penguin schrieb:

    Auf verschachtelte Vektoren kannst du mit Iteratoren zugreifen.

    Oder aber mit operator [], was doch wesentlich intuitiver sein dürfte, wenn man auf ein bestimmtes Element zugreifen möchte.


Log in to reply