Доступ к элементам вектора с использованием семантики указателя
элементам вектора можно также обратиться, используя подобную указателю семан тику итераторов (листинг 17.5).
ИСТИН Г 1 7 .5 . Доступ к элементам вектора с использованием
семантики указателя (итераторов)____________________________________________________________
#include
#include
:
int main ()
{
using namespace std;
vector veclntegers;
// Вставить в вектор целые числа:
9 veclntegers.push_back (50);
414 ЗАНЯТИЕ 17. Классы динамических массивов библиотеки STL
veclntegers.push_back (1);
veclntegers.push_back (987);
veclntegers.push_back (1001);
// Доступ к объектам в векторе с использованием итераторов:
vector ::iterator iElementLocator = veclntegers.begin ();
// итератор, объявленный с использованием ключевого
слова С++11 auto (следующая закомментированная строка)
17// auto iElementLocator = veclntegers.begin ();
18
19while (iElementLocator != veclntegers.end ())
{
size_t Index = distance (veclntegers.begin (),
22
|
|
|
|
iElementLocator);
|
23
|
cout
|
«
|
"Element
|
at position
|
";
|
24
|
25
|
cout
|
«
|
Index «
|
" is: " <<
|
^iElementLocator « endl;
|
26
|
|
|
|
|
|
// перейти к следующему элементу
++ iElementLocator;
}
30
return 0;
Результат
Element at position 0 is: 50
Element at position 1 is: 1
Element at position 2 is: 987
Element at position 3 is: 1001
Анализ
Итератор в этом примере ведет себя весьма похоже на указатель, и характер его при менения сходен с арифметикой адресов в указателе, как можно заметить в строке 25, где
хранящемуся в векторе значению обращаются с использованием оператора обращение
значению (*), и в строке 29, где инкремент итератора при помощи оператора ++ перево дит его на следующий элемент. Обратите внимание на использование в строке 21 метода s t d : : d i s t a n c e () для вычисления отсчитываемой от нуля позиции смещения элемента £
векторе (т.е. позиции относительно начала) по возвращаемому значению метода b e g in ( и указывающему на элемент итератору.
Удаление элементов из вектора
Подобно тому, как метод p u sh _ b a c k () обеспечивает вставку в конец вектора, метод p o p _ b ac k () обеспечивает удаление элемента из него. Удаление элемента из вектора при помощи метода p o p _ b a c k () занимает постоянное время, т.е. время удаления не зависит от количества хранящихся в векторе элементов. Код в листинге 17.6 демонстрирует ис пользование функции pop b a c k () для удаления элементов с конца вектора.
Типичные операции с вектором
|
415
|
ЛИСТИН Г 1 7 .6 . Использование метода pop back () для удаления последнего элемента
#include
#include
using namespace std;
template
void DisplayVector(const vector& veclnput)
{
for (auto iElement = veclnput.cbegin() // auto и cbegin(): C++11
8
|
;
|
iElement != Input.cend()
|
// cend() только C++11
|
9
|
;
|
++ iElement )
|
|
cout « *iElement « ' ';
cout « endl;
:з }
14
int main ()
{
vector veclntegers;
// Вставить в вектор целые числа:
:оveclntegers.push_back (50);
veclntegers.push_back (1);
veclntegers.push_back (987);
veclntegers.push_back (1001);
25 cout « "Vector contains " « veclntegers.size ()
" elements: ";
DisplayVector(veclntegers);
2 7
// Удалить один элемент в конце
veclntegers.pop_back ();
30
31 cout « "After a call to pop_back()" « endl;
32 cout « "Vector contains " « veclntegers.size ()
" elements: ";
DisplayVector(veclntegers);
return 0;
}
Результат
Vector contains 4 elements: 50 1 987 1001
After a call to pop_back()
Vector contains 3 elements: 50 1 987
Анализ
Вывод указывает, что метод p o p _ b a c k (), используемый в строке 29, сократил коли чество элементов в векторе, удалив последний вставленный в него элемент. В строке 32 следующий вызов метода s i z e () демонстрирует, что количество элементов в векторе со кратилось на одни, как свидетельствует вывод.
416 ЗАНЯТИЕ 17. Классы динамических массивов библиотеки STL
ПРИМЕЧАНИЕ
|
Функция DisplayVector () в строках 4-13 листинга 17.6 приняла форму
|
|
|
шаблона по сравнению с листингом 17.3, где она получала только вектор целых
|
|
чисел. Это позволит нам повторно использовать этот шаблон функции для век
|
|
тора типа float (вместо типа int):
|
|
vector vecFloats;
|
|
DisplayVector(vecFloats); // работает, поскольку это обобщение
|
|
function
|
|
Теперь она поддерживает вектор любого класса, который предоставляет опера
|
|
тор *, возвращающий значение, понятное оператору cout.
|
Концепция размера и емкости
Размер (size) вектора — это количество хранимых в нем элементов. Емкость (capacity ■ вектора — это общее количество элементов, которые могут быть сохранены в векторе прежде, чем повторное резервирование памяти позволит сохранить больше элементов Поэтому размер вектора меньше или равен его емкости.
Количество элементов в векторе можно выяснить, вызвав функцию s i z e ():
cout << "Size: " « veclntegers.size ();
Емкость возвращает функция c a p a c i t y ():
cout << "Capacity: " « veclntegers.capacity () « endl;
При частом повторном резервировании памяти для внутреннего динамического масси ва вектор может создать проблемы с производительностью. Эта проблема в значительной степени может быть решена при помощи функции-члена r e s e r v e (ч и сл о ) . По существу, она увеличивает объем памяти, резервируемой для внутреннего массива вектора, что по зволяет сохранять больше элементов без повторных резервирований. В зависимости от типа хранимых в векторе объектов, сокращение количества повторных резервирований сокращает также время копирования объектов и экономит производительность. Пример кода в листинге 17.7 демонстрирует различие между размером и емкостью.
И С ТИ Н Г 1 7 .7 . Демонстрация применения методов size () и capacity ()________________
#include
#include
:
int main ()
{
using namespace std;
:
// Создание экземпляра вектора, способного изначально
содержать 5 целых чисел
vector veclntegers (5);
9:
cout « "Vector of integers was instantiated with " « endl;
cout « "Size: " « veclntegers.size ();
Концепция размера и емкости
|
417
|
cout « ", Capacity: " « veclntegers.capacity () « endl;
// Вставка в вектор 6-го элемента
veclntegers.push_back (666);
16:
cout « "After inserting an additional element..." « endl;
cout « "Size: " « veclntegers.size ();
19: cout « ", Capacity: " « veclntegers.capacity () « endl;
2 0 :
// Вставка другого элемента
veclntegers.push_back (777);
cout « "After inserting yet another element... " « endl;
cout « "Size: " « veclntegers.size ();
cout « ", Capacity: " « veclntegers.capacity () « endl;
return 0;
}
Результат
Do'stlaringiz bilan baham: |