Iteratory
Iterator to obiekt, który może iterować elementy w kontenerze biblioteki standardowej języka C++ i zapewnić dostęp do poszczególnych elementów. Kontenery biblioteki standardowej języka C++ zapewniają iteratory, dzięki czemu algorytmy mogą uzyskiwać dostęp do swoich elementów w standardowy sposób bez konieczności zajmowania się typem kontenera, w jakim są przechowywane elementy.
Można używać iteratorów jawnie przy użyciu funkcji członkowskich i globalnych, takich jak i i, takich jak begin()
++
iend()
, --
aby przejść do przodu lub do tyłu. Można również używać iteratorów niejawnie z pętlą range-for lub (dla niektórych typów iteratorów) operatorem []
indeksu dolnego .
W standardowej bibliotece języka C++ początek sekwencji lub zakresu jest pierwszym elementem. Koniec sekwencji lub zakresu jest zawsze definiowany jako jeden obok ostatniego elementu. Funkcje begin
globalne i end
zwracają iteratory do określonego kontenera. Typowa pętla iteratora jawnego dla wszystkich elementów w kontenerze wygląda następująco:
vector<int> vec{ 0,1,2,3,4 };
for (auto it = begin(vec); it != end(vec); it++)
{
// Access element using dereference operator
cout << *it << " ";
}
To samo można zrobić bardziej po prostu za pomocą pętli range-for:
for (auto num : vec)
{
// no dereference operator
cout << num << " ";
}
Istnieje pięć kategorii iteratorów. W kolejności zwiększania mocy kategorie to:
Dane wyjściowe. Iterator
X
danych wyjściowych może iterować do przodu przez sekwencję przy użyciu++
operatora i może napisać element tylko raz przy użyciu*
operatora .Dane wejściowe. Iterator
X
wejściowy może iterować do przodu przez sekwencję przy użyciu++
operatora i odczytywać element dowolną liczbę razy przy użyciu*
operatora . Iteratory wejściowe można porównać przy użyciu==
operatorów i!=
. Po inkrementacji dowolnej kopii iteratora wejściowego żadna z innych kopii nie może być bezpiecznie porównywana, wyłuszczone lub zwiększana później.Dalej. Iterator
X
przesyłania dalej może iterować do przodu przez sekwencję przy użyciu operatora ++ i może odczytywać dowolny element lub zapisywać elementy inne niż const dowolną liczbę razy za pomocą*
operatora . Dostęp do elementów członkowskich można uzyskać za pomocą->
operatora i porównać iteratory przesyłania dalej za pomocą==
operatorów i!=
. Można utworzyć wiele kopii iteratora do przodu, z których każda może być wyłuszczone i zwiększana niezależnie. Iterator przesyłania dalej, który jest inicjowany bez odwołania do żadnego kontenera, jest nazywany iteratorem przekazywania o wartości null. Iteratory przesyłania dalej o wartości null zawsze są porównywane równe.Dwukierunkowe. Iterator
X
dwukierunkowy może mieć miejsce iteratora do przodu. Można jednak również dekrementować iterator dwukierunkowy, jak w--X
pliku ,X--
lub(V = *X--)
. Możesz uzyskać dostęp do elementów członkowskich i porównać iteratory dwukierunkowe w taki sam sposób, jak iteratory przesyłania dalej.Dostęp losowy. Iterator
X
dostępu losowego może mieć miejsce iteratora dwukierunkowego. Za pomocą iteratora dostępu losowego możesz użyć operatora[]
indeksu dolnego, aby uzyskać dostęp do elementów. Można użyć+
operatorów ,-
+=
i-=
, aby przejść do przodu lub do tyłu określoną liczbę elementów i obliczyć odległość między iteratorami. Można porównać iteratory dwukierunkowe przy użyciu==
poleceń , ,!=
,<
>
, ,<=
i>=
.
Wszystkie iteratory można przypisać lub skopiować. Zakłada się, że są to lekkie obiekty i są często przekazywane i zwracane przez wartość, a nie przez odwołanie. Należy również pamiętać, że żadna z opisanych wcześniej operacji nie może zgłosić wyjątku podczas wykonywania na prawidłowym iteratorze.
Hierarchia kategorii iteratorów można podsumować, wyświetlając trzy sekwencje. W przypadku dostępu tylko do zapisu do sekwencji można użyć dowolnego z:
iterator danych wyjściowych
-> iterator do przodu
-> iterator dwukierunkowy
-> iterator dostępu losowego
Strzałka w prawo oznacza, że "można zamienić na". Każdy algorytm, który wywołuje iterator danych wyjściowych, powinien działać ładnie z iteratorem do przodu, na przykład, ale nie w drugą stronę.
W przypadku dostępu tylko do odczytu do sekwencji można użyć dowolnego z:
iterator wejściowy
-> iterator do przodu
-> iterator dwukierunkowy
-> iterator dostępu losowego
Iterator danych wejściowych jest najsłabszy ze wszystkich kategorii, w tym przypadku.
Na koniec, aby uzyskać dostęp do odczytu/zapisu do sekwencji, można użyć dowolnego z:
iterator przesyłania dalej
-> iterator dwukierunkowy
-> iterator dostępu losowego
Wskaźnik obiektu może zawsze służyć jako iterator dostępu losowego, dzięki czemu może służyć jako dowolna kategoria iteratora, jeśli obsługuje odpowiedni dostęp do odczytu/zapisu do wyznaczonej sekwencji.
Iterator Iterator
inny niż wskaźnik obiektu musi również definiować typy składowe wymagane przez specjalizację iterator_traits<Iterator>
. Te wymagania można spełnić, Iterator
korzystając z iteratora klasy bazowej publicznej.
Ważne jest, aby zrozumieć obietnice i ograniczenia każdej kategorii iteratora, aby zobaczyć, jak iteratory są używane przez kontenery i algorytmy w standardowej bibliotece języka C++.
Uwaga
Można unikać jawnego używania iteratorów przy użyciu pętli range-for. Aby uzyskać więcej informacji, zobacz Range-based for statement (Zakres oparty na instrukcji).
Program Microsoft C++ oferuje teraz sprawdzone iteratory i iteratory debugowania, aby upewnić się, że nie zastąpisz granic kontenera. Aby uzyskać więcej informacji, zobacz Sprawdzone iteratory i Obsługa iteratora debugowania.
Zobacz też
Dokumentacja standardowej biblioteki C++
Bezpieczeństwo wątku w standardowej bibliotece C++