Qt - kontener typu QVector

Autor podstrony: Krzysztof Zajączkowski

Stronę tą wyświetlono już: 3121 razy

Klasa QVector jest kolejnym typem kontenera wchodzącego w skład biblioteki Qt. Dysponuje on praktycznie tymi samymi metodami co omawiana klasa QList, jest jednak pewna zasadnicza różnica w tym, jak realizowane jest przechowywanie danych w pamięci. Okazuje się bowiem, że QVector zawsze przechowuje w pamięci elementy tak, że te zajmują kolejne miejsca w pamięci komputera podczas gdy QList przechowuje swoje elementy na stercie, chyba że rozmiar przechowywanych danych jest mniejszy lub równy rozmiarowi typu void*.

Klasa QVector umożliwia szybkie iterowanie po dużej liczbie elementów, ale dodawanie i usuwanie elementów z wnętrza nie jest tak szybkie jak w przypadku klasy QList co ma znaczenie zwłaszcza przy dużej liczbie danych i dużej ilości takich operacji.

Dodawanie elementów do obiektu klasy QVector

Dodanie kolejnych elementów można przeprowadzić na kilka różnych sposobów, jednym z nich jest przypisanie w stylu C++ 11:

QVector<int> vector = {10, 20}; qDebug() << vector;

Można również dodawać na różne sposoby kolejne elementy:

QVector<int> vector = {10, 20}; qDebug() << vector; vector.append(30); vector.append({40, 50}); qDebug() << vector; vector.prepend(60); qDebug() << vector; vector << 70 << 80; qDebug() << vector; vector += 90; vector += {100, 110}; qDebug() << vector; vector.push_back(120); vector.push_front(130); qDebug() << vector; vector.insert(vector.begin() + 2, 130); qDebug() << vector;

Wynik działania powyższego kodu:

QVector(10, 20)
QVector(10, 20, 30, 40, 50)
QVector(60, 10, 20, 30, 40, 50)
QVector(60, 10, 20, 30, 40, 50, 70, 80)
QVector(60, 10, 20, 30, 40, 50, 70, 80, 90, 100, 110)
QVector(130, 60, 10, 20, 30, 40, 50, 70, 80, 90, 100, 110, 120)
QVector(130, 60, 130, 10, 20, 30, 40, 50, 70, 80, 90, 100, 110, 120)

Pozyskiwanie informacji o liczbie elementów zawartych

Istnieją dwie metody length i size, które zwracają liczbę elementów zawartych w obiekcie klasy QVector.

Iterowanie po elementach wektora

Iterowanie można wykonać na kilka sposobów. Pierwszy z nich wykorzystuje indeksowanie:

QVector<int> vector = {10, 20, 30}; for(int i = 0; i < vector.length(); i++){ qDebug() << vector[i]; // opcjonalnie vector.at(i) }

Można też iterować wykorzystując wskaźniki:

QVector<int> vector = {10, 20, 30}; for(QVector<int>::iterator i = vector.begin(); i < vector.end(); i++){ qDebug() << *i; }

Jeżeli dodana została obsługa standardu C++ 11 można sobie ułatwić życie iterując w następujący sposób:

QVector<int> vector = {10, 20, 30}; for(auto element: vector){ qDebug() << element; }

I w końcu można iterować po elementach listy w stylu Javy:

QVector<int> vector = {10, 20, 30}; QVectorIterator<int> javaStyleIterator(vector); while (javaStyleIterator.hasNext()) qDebug() << javaStyleIterator.next();

Znalezienie indeksu pierwszego lub ostatniego wystąpienia danej wartości w wektorze

By znaleźć ostatni lub pierwszy indeks, pod którym znajduje się szukana wartość należy skorzystać z metody indexOf lub lastIndexOf w następujący sposób:

QVector<int> vector = {10, 20, 30}; int index = vector.indexOf(20); if(index != -1){ qDebug() << index; }

Usuwanie elementów z wektora

Istnieje szereg metod, które umożliwiają usuwanie elementów z wektora QVector. Oto przykład ich użycia:

QVector<int> data = {100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800}; qDebug() << data; data.removeAll(600); // usuwam wszystkie wartości równe 600 qDebug() << data; data.removeFirst(); // usuwam pierwszy element qDebug() << data; data.removeLast(); // usuwam ostatni element qDebug() << data; data.removeAt(2); // usuwam 3 element (indeksowanie od 0) qDebug() << data; data.remove(4); // usuwa 5-ty element qDebug() << data; data.remove(1, 3); // usuwa trzy elementy zaczynając od drugiego qDebug() << data; data.erase(data.begin() + 1); // usuwanie drugiego elementu qDebug() << data;

Wynik działania powyższego kodu:

QVector(100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800)
QVector(100, 200, 300, 400, 500, 700, 100, 300, 400, 500, 700, 800)
QVector(200, 300, 400, 500, 700, 100, 300, 400, 500, 700, 800)
QVector(200, 300, 400, 500, 700, 100, 300, 400, 500, 700)
QVector(200, 300, 500, 700, 100, 300, 400, 500, 700)
QVector(200, 300, 500, 700, 300, 400, 500, 700)
QVector(200, 300, 400, 500, 700)
QVector(200, 400, 500, 700)

Zdejmowanie pierwszego, ostatniego lub i-tego elementu wektora

Metody takeFirst. takeLast i takeAt umożliwiają zdjęcie pierwszego, ostatniego i i-tego elementu wektora z jednoczesnym jego zwróceniem.

QVector<int> data = {100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800}; qDebug() << data; qDebug() << "Get first one: " << data.takeFirst(); qDebug() << "After remove first one: " << data; qDebug() << "Get last one: " << data.takeLast(); qDebug() << "After remove last one: " << data; qDebug() << "Get 3rd one: " << data.takeAt(2); qDebug() << "After remove 3rd one: " << data;

Wynik działania powyższego kodu:

QVector(100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800)
Get first one:  100
After remove first one:  QVector(200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800)
Get last one:  800
After remove last one:  QVector(200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700)
Get 3rd one:  400
After remove 3rd one:  QVector(200, 300, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700)

Wyciąganie części elementów z wnętrza wektora

Metoda mid umożliwia wyciągnięcie dowolnej liczby elementów z wnętrza wektora. Oto przykład:

QVector<int> data = {100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800}; QVector<int> subData = data.mid(3, 5); qDebug() << data; qDebug() << subData;

Wynik działania powyższego kodu:

QVector(100, 200, 300, 400, 500, 600, 600, 700, 100, 300, 400, 500, 600, 700, 800)
QVector(400, 500, 600, 600, 700)

Przenoszenie elementu wektora

Metoda move umożliwia przeniesienie elementu o podanym indeksie na inną pozycję:

QVector<int> data = { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}; qDebug() << data; data.move(5, 10); qDebug() << data;

Wynik działania powyższego kodu:

QVector(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0)
QVector(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)

Łączenie dwóch wektorów

Łączenie dwóch wektorów umożliwia operator dodawania z podstawianiem += oraz dodawania +. Oto przykład:

QVector<int> data = {0, 1, 2}; QVector<int> data2 = {3, 4, 5, 6}; qDebug() << data + data2; data2 += data; qDebug() << data2;

Wynik działania powyższego kodu:

QVector(0, 1, 2, 3, 4, 5, 6)
QVector(3, 4, 5, 6, 0, 1, 2)

Zamiana elementów wektorów miejscami

Jeżeli zachodzi konieczność zamiany miejscami elementów dwóch wektorów, to najszybszą metodą wykonania tego zadania jest użycie metody swap w następujący sposób:

QVector<int> data = {0, 1, 2}; QVector<int> data2 = {3, 4, 5, 6}; qDebug() << "Before swap: data =" << data << "data2 =" << data2; data.swap(data2); qDebug() << "After swap: data =" << data << "data2 =" << data2;

Wynik działania powyższego kodu:

Before swap: data = QVector(0, 1, 2) data2 = QVector(3, 4, 5, 6)
After swap: data = QVector(3, 4, 5, 6) data2 = QVector(0, 1, 2)
Strony powiązane
strony powiązane
  1. doc.qt.io/qt-5/qvector.html - strona dokumentacji Qt z opisem klasy QVector
Propozycje książek