[gelöst] QVector und die Alternativen

Alles rund um die Programmierung mit Qt
Antworten
jimmy
Beiträge: 24
Registriert: 10. August 2005 11:39

[gelöst] QVector und die Alternativen

Beitrag von jimmy »

Hi,
ich kann mich einfach nicht entscheiden, was ich nehmen soll.
Ich brauche ein dynamisches 2-diminsionalles Array of QString und frage mich ob ich einfach QVector verwenden soll oder doch QVarLengthArray? Welche unterschiede gibt es da? Und wie kann ich bei beiden 2-dim deklarieren ? :oops:
Zuletzt geändert von jimmy am 27. Oktober 2005 19:47, insgesamt 1-mal geändert.
lepsai
Beiträge: 573
Registriert: 14. September 2004 21:33
Wohnort: Berlin
Kontaktdaten:

Beitrag von lepsai »

Ein 2D-Vektor heisst in der Umgangssprache eine Matrix :)
Eine nicht besonders effiziente Umsetzung davon hat die Form:

typedef vector<vector<data_type> > meine_matrix_klasse;

Besser ist etwa sowas:

Code: Alles auswählen

class matrix
{
public:

   matrix(int x, int y)
   {
        m_data.resize(x*y);
        m_width = x;
        m_height = y;
   }
    
   QString value(int x, int y)
   {
        return m_data.at(x + y*width() );
   }
   
   void setValue(int x, int y, const QString & v)
   {
        m_data.at(x + y*width() ) = v;
   }

protected:
     QVector <QString> m_data;
     unsigned m_width, m_height;
};
Am besten ist es aber auf QVector ganz zu verzichten und stattdessen QString * m_pData verwenden.
klogg
Beiträge: 129
Registriert: 5. September 2005 17:00
Wohnort: Hann. Münden

Beitrag von klogg »

Falls du die Sammlung oft veränderst, würde ich QList empfehlen.
Nutzt eine verkette Liste zum Speichern der Objekte
und einen Array mit Adressen für schnellen []-Zugriff.

HENNING
jimmy
Beiträge: 24
Registriert: 10. August 2005 11:39

Beitrag von jimmy »

Danke für die Vorschläge. Die QList klingt ja verlockend, aber es macht wohl zu viele Umstände dort etwas an einer bestimmten Stelle hinzuzufügen. Das heisst, ich musste als 2 Dimension vllt ein festes "normales" Array nehmen. Die arrays pack ich dann in die Liste, weil die Reihenfolge für mich egal ist. Das eigentliche Element soll aber aus 8 Strings bestehen, und jedes soll auch eigenen index haben, d. h. QList (ein Topf) passt nicht. Somit wäre das dynamisch und die Elemente wären, wie geplant, Arrays mit 8 reservierten Plätzen. Denn manchmal müssen einige Stellen leer bleiben. Soweit also, nehme ich eine QList und schreibe dort normale C++ arrays rein. Geht das besser oder reicht das? Ich könnte ja auch einfach eine Matrix aus QVector verwenden, aber das wäre langsamer, oder? Die Liste wird nie mehr als 100 Elemente haben, aber es soll trotzdem dynamisch sein.
klogg
Beiträge: 129
Registriert: 5. September 2005 17:00
Wohnort: Hann. Münden

Beitrag von klogg »

Es gibt eine von QList abgeleitete Klasse QStringList.
Die bietet einige sehr nützliche Funktionen und ist besonders dann interessant,
wenn man einen QString (z.B. aus einer Datei) trennen will.
Du kannst nämlich einem QString "sagen", dass er sich bei einem bestimmten Trennzeichen zerlegen soll.
Das Ergebnis kriegst du dann als QStringList zurück.

In deinem Fall könntest du also mit QList<QStringList> arbeiten.
(QStringList ist natürlich kein Template mehr)
Zugriffe wie liste[4][2] sind dann möglich.

Am besten liest du dir mal die Dokumentation der QStringList durch.
http://doc.trolltech.com/4.0/qstringlist.html

HENNING
klogg
Beiträge: 129
Registriert: 5. September 2005 17:00
Wohnort: Hann. Münden

Beitrag von klogg »

jimmy hat geschrieben:Soweit also, nehme ich eine QList und schreibe dort normale C++ arrays rein.
Dann müsstest du die Arrays selbst allokieren.
Das würde bedeuten, du speicherst in der Liste nur deren Adressen.
QList<*QString> und QList->append(new QString[8])
liste[3][3] funktioniert jetzt zwar, aber du musst den Speicher selbst wieder freigegben.

HENNING
jimmy
Beiträge: 24
Registriert: 10. August 2005 11:39

Beitrag von jimmy »

Thx, aber ich kann dann nicht z.B (QStringList) liste[5]<<"bla". Ich meine irgendwas an einer bestimmten Stelle hinzuzufügen, sondern immer nur draufpacken, wie in einen Topf.
Also QList werde ich verwenden, aber die Elemente darin... Ich brauche ein Array als element, mit 8 initialisierten Plätzen, damit ich eben auch an der z. B 5. Stelle was reinschreiben kann. Würde ich QStringList verwenden, müsste ich 8 leere Strings reinschreiben und dann den 5. überschreiben. Ausserdem habe ich grosse Probleme überhaupt etwas 2 - dimensionalles zu initialisieren :(
lepsai
Beiträge: 573
Registriert: 14. September 2004 21:33
Wohnort: Berlin
Kontaktdaten:

Beitrag von lepsai »

Beschreibe mal ganz genau, welche Art Datenstruktur du brauchst. Ich verstehe es langsam nicht mehr...
jimmy
Beiträge: 24
Registriert: 10. August 2005 11:39

Beitrag von jimmy »

Ok nun hab ich etwas hingekriegt :)
Ich habe z. Z. QList<QVector<QString> >deviceist
Die initialisierung:
for (int j=0;j<50;j++){
QVector<QString> list( 8 );
devicelist << list;
}
So hab ich halt am anfang 50 Vectoren in der QList.
Nun funktioniert alles, ohne im quellcode etwas zu ändern. Und in die QList kann ich ja so viele Vectoren reinschreiben , wie ich will. Ich muss halt dann nen neuen Vector erstellen.

Die Datenstruktur sieht so aus: Es soll ein dynamisches Array sein, in dem jedes Element ein Array[8] ist. Da ja Qt die klassen anbietet, möchte ich kein C++ array benutzen.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Es soll ein dynamisches Array sein, in dem jedes Element ein Array[8] ist. Da ja Qt die klassen anbietet, möchte ich kein C++ array benutzen.
ein std::vector oder QVector ist ne Komfortklasse fuer nen dynamisch allokierte Felder , und damit niemalsnich nen ersatz fuer statische arrays !

Wer nen durch die aufgabenstellung vorgschriebenes unsigned char data[255]; z.b. durch nen vector<unsigned char> data, eresetzt, der gehoert in die Performance-Hoelle :-)

In deinem Fall wuerd ich mir vielleicht sowas bauen :

Code: Alles auswählen

template<class AT,size_t SIZE>
class StaticArray
{
// dem teil nen statisches array als member geben .... 
private: 
    AT mdata[SIZE];
// und dann alles was man braucht implementieren .... 
// fuer die verwendung in den containern brauchst auf alle faelle nen CCTOR, Index operator und zueweisungsop waeren sicher auch ned schlecht .... 
};

typedef StaticArray<char,8> MyDataClass;

QVector<MyDataClass> myArray; 
um einmal kopieren wirst eh nich drumherumkommen .... da die objecte nie im dynamischen Array selber erstellen kannst ....

Man muss nich auf teufel komm raus die QT container verwenden ... , verwendest container in ner Multithreaded umgebung, wuerd ich auf die QT container eh verzichten, weil das verhalten implementationsbedingt ist durch das COW. stl container sind definierter, was das verhalten anbelangt ... dafuer muss man sich expliziet mehr gedanken um die performance machen, da die meist nicht selbst optimieren. in der STL muss man programmieren was man braucht (Mehrarbeit) die QT baut das was sie denkt was du brauchst ... hat aber oftmals dann auch recht damit :-)

Ciao ...
jimmy
Beiträge: 24
Registriert: 10. August 2005 11:39

Beitrag von jimmy »

hiho, tjoa... ist zwar sehr nett von dir, aber ich bin noch am Lernen und verstehe nicht ganz was du vorgeschlagen hast :(
Und selber was bauen... das kann ich leider noch nicht. Qt lerne ich nach "try and Error" und im netz gibt speziell für Qt4 noch nicht soo viel.
Also verwende ich erstmal ne QList voller QVector. Wer weiss, vllt muss ich das array[8] ( jetzt QVector( 8 ) ) mal erweitern.
Antworten