|
Программирование >> Формирование пользовательского контейнера
-3 -2 -1 Разработанный контейнер типа RangeArray позволяет вам создать такои массив. Более того, вы сможете задавать произвольные верхнюю и нижню фаницы для индексирования элементов массива. сопоставления. В пользовательском контейнере можно определить дополнительные конструкторы. Примечание j2 Конструкторы всех встроенных ассоциативных контейнеров библиотеки STL, за исключением копирующего конструктора, принимают аргумент, задающий рас-пределитель памяти (по умолчанию типа allocator), но его указание не является обязательным требованием. Ассоциативные контейнеры должны предоставлять следующие дополнительные функции-члены: count() equal range() f ind() key comp() 1ower bound() upper bound() value comp() Создание контейнера для динамического массива с настраиваемым диапазоном в оставшейся части этой главы разрабатывается пользовательский последовательный контейнер типа RangeArray, предоставляющий динамический массив с настраиваемым диапазоном индексов. Несмотря на то, что пример, приведенный далее, иллюстрирует создание последовательного контейнера, большая часть идей (или решений) также применима для реализации ассоциативных контейнеров. Принцип действия контейнера RangeArray Как вы знаете, в стандартном языке С++ нумерация элементов массива начинается с О, и использовать отрицательные индексы запрещено. Однако некоторые приложения выифали бы от применения массива, в котором профаммисту разрешено задавать разные фаницы. Рассмотрим плоскость декартовых координат: каждая ось - линия, на которой располагаются и положительные, и офицательные значения. Удобным способом представления такой линии в профамме было бы применение массива, в котором допустимы положительные и офицательные значения индексов. Например, имея офезок, изменяющийся от -5 до 5, вы могли бы использовать массив, который индексировался бы следующим образом: яапдеАггау - динамический контейнер, допускающий увеличение массива как в положительном, так и в отрицательном направлениях. В этом отношении он подобен встроенному контейнеру, вектору. Контейнер RangeArray поддерживает все требуемые от последовательного контейнера операции, ллюс дополнительную операцию индексирования [] и необязательные функции: at (), push front (), pop front () И T. Д. Вы можете написать следующий фрагмент кода, иллюстрирующий использование контейнера RangeArray: Создается массив с границами от -3 до 4 и инициализируется с нулевыми значениями. BangeArray<int> ob (-3, 4, О); Присваивает значения от -3 до 4 элементам массива ob. for (int I = -3; I < 5; i++) ob[i] = 1; ... cout ob(-2] ; -... 6bt2] = ob[-l] % 2; Как вы могли догадаться, первая строка конструирует объект типа RangeArray с диапазоном изменения индекса от -3 до 4, каждый элемент объекта инициализирован с нулевым значением. Остальные строки фрагмента кола показывают, что к элементам массива возможен доступ в заданном диапазоне изменения индекса. Вообще, тип RangeArray позволяет создавать объекты, задавая нижнюю и верхнюю фаницы массива и значение, применяемое при инициализации каждого его элемента. Другими словами, контейнер RangeArray содержит следующий вариант конструктора: RangeArray (1 owerbound, upperbound, ini cvalue) После того как массив создан, к нему можно применять операцию индексирования с любым значением индекса из заданного диапазона. Это означает, что разрешены любые значения индекса, включая офицательные. Поскольку массив типа RangeArray динамический, В него можно вставлять Цементы и удалять их. Эти операции вызывают увеличение или сжатие Массива соответственно. Важно то, что может меняться любая фанииа массива. Если добавляется элемент с офицательным значением индекса, то Увеличивается офицательная часть диапазона. Если же удаляется элемент положительным значением индекса, то сжимается положительная часть Интервала. Следует также обратить внимание на то, что реализация контейнера ngeArray намеренно не оптимизирована для повышения производитель- Полное описание класса RangeArray Для начала в листинге 8.1 приведен полный код контейнера типа RangeArray. Стоит только начать создавать собственные контейнеры, как вы сразу обнаружите, что даже простой контейнер преврашается в довольно большой класс. Причина, конечно, заключена в ряде требований, которые необходимо удовлетворить. Несмофя на то, что любое из фебований само по себе не сложно, в комбинации они порождают значительный объем кода. Не пугайтесь, весь код будет подробно проанализирован в последующих разделах. Листинг 8.1. Пользовательский контейнер, реализующий массив с настраиваемым диапазоном Назовите этот файл ra.h. #include <iostreain> #include <iterator> #include <algorithm> #include <cstdlib> #include <stdexcept> using namespace std; Класс-исключение для RangeArray. class RAExc { string err; public: RAExc(string e) { err = e; string geterr0 { return err; } ности. Более того, при разработке профаммы главным критерием оптимизации бьша наибольшая ясность и доходчивость кода. Задача приводимого примера - четко продемонсфировать все шаги, необходимые для создания пользовательского контейнера. Для облегчения понимания предлагаемая профамма написана достаточно прямолинейно, без хитростей. Работа над ее усовершенствованием может доставить вам удовольствие.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |