C++ Newbie und vector bzw. zwei Dim. vector

  • Hallo,


    ich habe Probleme mit zwei Dim. Vectoren, ich möchte ein zwei Dim. "Array" aufbauen das folgendermassen aussieht:


    Die Daten hole ich mir aus einer Datei (liste):


    Dazu habe ich mir folgenden Code gebastelt, was so auch funktioniert.
    Was ich an dieser Stelle nicht 100%ig kapiere ist "vector< vector<string> >liste(BLOCK);" --> dies müsten zwei verschachtelte Vectoren vom Typ <string> mit jeweils 500 intialisierten Felder "BLOCK=500;" sein (??) !



    Ausgabe:


    Nun versuche ich das ganze mit einer Klasse zu realisieren:



    Ausgabe:


    Allerdings ist das Beispiel jetz eigentlich falsch, das es sich um zwei eigenständige Vectoren handelt!
    Dies habe ich auch nur Versucht um zu sehen, ob man den Vector in einer Klasse definieren kann.


    Das Ziel ist es eigentlich einen zwei Dim. Vector in der Klasse zu initalisieren, damit die anderen Klassenmember ebenfalls auf das "Array" bzw. auf den vector zugreifen können --> dies gelingt mir aber nicht :( !!!


    Durch langes probieren meckert der Compiler nicht mehr wenn ich in der Private Class folgendes deklariere (aber ob das richtig ist?):


    Code
    static const int BLOCK1=500;
      vector< vector<string> >liste(int BLOCK1);


    Nur habe ich dann folgendes Problem wenn ich "liste.push_back(text);" in v_array::set" einfüge:


    Code
    void v_array::set (int pos, string text)
    {
      v_pos.push_back(pos);
      v_text.push_back(text);
      liste.push_back(text);      <--- ZEILE 35
    }


    Zitat


    test.c: In member function ‘void v_array::set(int, std::string)’:
    test.c:35: error: ‘((v_array*)this)->v_array::liste’ does not have class type


    Habe schon gegoogelt aber ich verstehe dies alles nicht so recht, ich denke man muss das irgendwie mit Pointern lösen (aber soweit bin ich noch nicht, bzw. ich erlese es mir erst gerade ?( ).


    Sicherlich könnte man dies auch mit einem echten Array "liste[block][text]" lösen, aber wenn ich es richtig gelesen habe ist der c++ Weg der mit den Vectoren (?), aber viele Wege führen nach Rom und ich möchte es eigentlich nun auch verstehen was da nicht funktioniert.


    Gruß.
    Chuck

    1- yavdr 0.5 - DVB-C
    1- VDR-1.7.14 - Xine Pugin - XBMC - DVB-C
    2- Activy 300 mit Gen2VDR V2

  • Code
    static const int BLOCK1=500;
      vector< vector<string> >liste(int BLOCK1);


    Definiert eine Funktion namens liste, die einen Parameter namens BLOCK1 vom Typ int annimmt und einen vector von string-vectoren zurückgibt. Definiert kein Member-Feld namens liste.


    Zitat


    test.c: In member function ‘void v_array::set(int, std::string)’:
    test.c:35: error: ‘((v_array*)this)->v_array::liste’ does not have class type


    Daraus folgt dieser Fehler: Eine Funktion hat keine Methoden.


    Und die Pointer kannst Du getrost weglassen (überhaupt gibt es gerade in C++ viele Möglichkeiten ohne Pointer auszukommen, und VDR geht da nicht mit bestem Beispiel voran). Das Problem (oder eher, die Eigenschaft) ist hier dass Du beim definieren einer Klasse die Member-Felder auch nur definierst, nicht initialisierst. Das geschieht erst im Konstruktor der Klasse. Konkret sieht das dann so aus:



    BTW: Das (void) in leeren Parameterlisten ist ein Anachronismus: In C++ genügen leere Klammern. Habe ich selbst lange Zeit gemacht, wollte es auch nur mal anmerken.

  • Hallo LordJaxom,


    vielen Dank darauf wäre ich NIE gekommen --> es funktioniert jetzt :) !


    Spricht etwas dagegen den Vector nicht statisch zu deklarieren, sondern zur Laufzeit wachsen lassen --> funktioniert auf jedenfall bei den ersten Tests?



    Gruß,
    Chuck

    1- yavdr 0.5 - DVB-C
    1- VDR-1.7.14 - Xine Pugin - XBMC - DVB-C
    2- Activy 300 mit Gen2VDR V2

  • Nö, spricht nichts gegen - dafür ist vector gedacht, dass Du Dich nicht mehr um den Speicher kümmern musst. BTW: push_back vergrößert den vector selbst, mit resize legst Du vor dem gepushten sogar noch leere Elemente an. Du darfst aber dem vector mit reserve bzw. dem Konstruktorparameter (oder mit resize vor einem set oder assign) sinnvolle Hinweise geben, wieviele Elemente Du hinzuzufügen gedenkst, das hilft der Speicherverwaltung dabei nicht unnötig oft neu allokieren zu müssen.

  • Zitat

    Original von LordJaxom
    Nö, spricht nichts gegen - dafür ist vector gedacht, dass Du Dich nicht mehr um den Speicher kümmern musst. BTW: push_back vergrößert den vector selbst, mit resize legst Du vor dem gepushten sogar noch leere Elemente an. Du darfst aber dem vector mit reserve bzw. dem Konstruktorparameter (oder mit resize vor einem set oder assign) sinnvolle Hinweise geben, wieviele Elemente Du hinzuzufügen gedenkst, das hilft der Speicherverwaltung dabei nicht unnötig oft neu allokieren zu müssen.


    Da muss ich nochmal vorsichtig nachfragen:
    In meinen obigen Beispiel habe ich den Eintrag

    Code
    //  static const int BLOCK=500;

    mit einem Kommentar versehen sowie den Konstruktur ohne BLOCK

    Code
    v_array::v_array(): v_text()

    initalisiert (ups ich sehe gerade das hatte ich in den Codeschnipsel nicht drinne).


    Somit hat der Vector keine Grösse und kann auch nicht per push_back vergrößert werden?
    Deswegen rezise ich den vector vor jeden Eintrag um nicht an BLOCK=500 gebunden zu sein.


    Ist das so sinnvoll, oder reseviert man direkt eine gewisse Größe und erhöht diese per rezise bei Bedarf?


    Ich hatte es auf jedenfall getestet ohne einen Wert im Konstrutor für das Array, und push_back alleine ohne rezise hatte nicht funktioniert (Speicherzugriffsfehler).


    Gruß,
    Chuck

    1- yavdr 0.5 - DVB-C
    1- VDR-1.7.14 - Xine Pugin - XBMC - DVB-C
    2- Activy 300 mit Gen2VDR V2

    Einmal editiert, zuletzt von vdrchuck ()

  • Also push_back muss definitiv ohne eine explizite Initialisierung (c'tor, resize) des Vectors funktionieren.


    Eine initiale Grösse wäre eine anzunehmende Durchschnittsgrösse deines Vectors. Ein nachträgliches resize ist durchaus sinnvoll und sollte entsprechend dem Geschwindigkeitsvorteil/Speichervebrauch abgewogen werden.


    Bei wirklich grossen Arrays würd ich jedoch kein STL nutzen ;)


    arghgra

  • Ansichtssache, kommt auch auf den allocator an ;)


    vdrchuck:
    Wie ich (und arghgra) sagte: push_back vergrößert den vector eigenständig wenn nötig, dafür ist es da. Wenn Du größere Blöcke auf einmal reinschreibst und deren Größe kennst bietet sich eher an resize und anschliessend at zu benutzen. Wenn Du dabei Speicherzugriffsfehler bekommst, machst Du etwas falsch (tm) ;)

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!