Шрифт:
Интервал:
Закладка:

В этой и следующих двух главах мы покажем, как построить класс vector, используя основные языковые возможности, доступные любому программисту. Это сделано для того, чтобы проиллюстрировать полезные концепции и методы программирования и показать, как их можно выразить с помощью средств языка С++. Языковые возможности и методы программирования, использованные при реализации класса vector, весьма полезны и очень широко используются.
Разобравшись в вопросах проектирования, реализации и использования класса vector, мы сможем понять устройство других стандартных контейнеров, таких как map, и испытать элементные и эффективные методы их использования, обеспечиваемые стандартной библиотекой языка C++ (подробнее об этом речь пойдет в главах 20 и 21). Эти методы, называемые алгоритмами, позволяют решать типичные задачи программирования обработки данных. Вместо самостоятельной разработки кустарных инструментов мы можем облегчить написание и тестирование программ с помощью библиотеки языка C++. Мы уже видели и использовали один из наиболее полезных алгоритмов из стандартной библиотеки — sort().

• Глава 17. Как работать с разными объемами памяти? В частности, как создать разные векторы с разным количеством элементов и как отдельный вектор может иметь разное количество элементов в разные моменты времени? Это приведет нас к проверке объема свободной памяти (объема кучи), указателям, приведению типов (операторам явного приведения типов) и ссылкам.
• Глава 18. Как скопировать вектор? Как реализовать оператор доступа к элементам по индексу? Кроме того, мы введем в рассмотрение массивы и исследуем их связь с указателями.
• Глава 19. Как создать векторы с разными типами хранящихся в них элементов? Как обрабатывать ошибку выхода за пределы допустимого диапазона? Для ответа на этот вопрос мы изучим шаблоны языка С++ и исключения.
Кроме новых свойств языка и методов программирования, изобретенных для создания гибкого, эффективного и безопасного с точки зрения типов вектора, мы будем также использовать (в том числе повторно) многое из описанного ранее. В некоторых случаях мы сможем даже привести более формальное определение.
Итак, все упирается в прямой доступ к памяти. Зачем нам это нужно? Наши классы vector и string чрезвычайно полезны и удобны; их можно просто использовать. В конце концов, контейнеры, такие как vector и string, разработаны именно для того, чтобы освободить нас от неприятных аспектов работы с реальной памятью. Однако, если мы не верим в волшебство, то должны освоить самый низкий уровень управления памятью. А почему бы нам не поверить в волшебство, т.е. почему бы не поверить, что разработчики класса vector знали, что делают? В конце концов, мы же не разбираем физические устройства, обеспечивающие работу памяти компьютера.


17.2. Основы
Начнем нашу поступательную разработку класса vector с очень простого примера.
vector<double> age(4); // вектор с четырьмя элементами типа double
age[0]=0.33;
age[1]=22.0;
age[2]=27.2;
age[3]=54.2;
Очевидно, что этот код создает объект класса vector с четырьмя элементами типа double и присваивает им значения 0.33, 22.0, 27.2 и 54.2. Эти четыре элемента имеют номера 0, 1, 2 и 3. Нумерация элементов в стандартных контейнерах языка С++ всегда начинается с нуля. Нумерация с нуля используется часто и является универсальным соглашением, которого придерживаются все программисты, пишущие программы на языке С++. Количество элементов в объекте класса vector называется его размером. Итак, размер вектора age равен четырем. Элементы вектора нумеруются (индексируются) от 0 до size-1. Например, элементы вектора