Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_otvety_k_ekzamenu.doc
Скачиваний:
55
Добавлен:
13.04.2015
Размер:
786.94 Кб
Скачать

23. Применение контейнера std::vector для композиции с недетерминированной кратностью. Композиция объектов-значений и объектов-сущностей.

Вектор является одним из классов-контейнеров стандартной библиотеки шаблонов (STL - Standard Template Library). STL-контейнеры, такие как вектор, представляют собой реализацию классических структур данных, ранее рассмотренных в обеспечивающей дисциплине. Подобные мощные утилитарные классы для классических структур имеются во всех современных языках программирования, и С++ не является исключением.

Простейшие типовые операции, характерные векторам, доступны через методы класса std::vector, среди них такие массово используемые во многих программах:

● size - возвращает число хранимых элементов;

● empty - выясняет пуст ли вектор;

● clear - очищает вектор;

● push_back - добавляет новый элемент в конец вектора

● pop_back - удаляет элемент с конца вектора;

● оператор индексной выборки [] - доступ к элементу с конкретным индексом без проверки;

● at - доступ к элементу с конкретным индексом с проверкой на выход за границу;

● insert - вставляет элемент в указанную конкретную позицию (с автоматическим сдвигом);

● erase - удаляет элемент из указанной конкретной позиции (с автоматическим сдвигом)

Реализация вектора из стандартной библиотеки полностью берет на себя ответственность за управление необходимой динамической памятью. В ней определены нужные конструкторы, операторы и деструктор, автоматически выделяющие и освобождающие память внутренних данных без необходимости вмешательства со стороны программиста.

Помимо того, что такая реализация предоставляет решение основной проблемы - динамическое изменение количества фиксируемых объектов - благодаря использованию вектора удается достичь существенных упрощений реализации:

● нет необходимости в передаче и извлечении максимального числа объектов;

● исчезает необходимость в явном деструкторе, поскольку деструктор вектора, который освободит выделенный блок памяти, будет автоматически вызван из генерируемого компилятором автоматического деструктора класса;

● исчезает необходимость в запрещении конструктора копий, поскольку реализация класса std::vector обладает функциональностью корректного копирования своего содержимого, и никаких "висячих" указателей в автоматическом конструкторе копий не возникнет;

● вектору также можно доверить проверку индексов при доступе к конкретным объектам.

Основная отличительная особенность любых объектов-значений - возможность свободного копирования и присвоение подобно встроенным типам. Наличие у объектов-точек такой возможности позволило легко поместить их в вектор.

Часто существует необходимость во множественной композиции объектов-сущностей, которые, как правило, не предполагают или даже полностью запрещают копирование, поскольку двух одинаковых объектов-сущностей в программе одновременно существовать не должно. Из невозможности копирования объектов вытекает невозможность помещения объектов в вектор. Также в вектор нельзя помещать ссылки на объекты, поскольку ссылка не является копируемой в принципе. Очевидно, в таком случае остается лишь одно решение - вместо объектов или ссылок на объекты в вектор следует поместить указатели на объекты. Указатели могут копироваться и имеют значение по умолчанию не зависимо от типа данного (nullptr).

Отдельного внимания требуют случаи, когда родительский объект является ответственным за уничтожение дочерних объектов-сущностей. Помещение указателя на некоторый объект в вектор не является причиной для его автоматического уничтожения (вектор не может догадаться о намерении программиста), и в таких случаях следует позаботиться об уничтожении вручную.

Как видно из приведенной реализации, внедрение векторов вместо массивов позволило также достичь ряда заметных упрощений, среди которых следующие:

● полностью исчезла какая-либо необходимость в собственном конструкторе, т.к. более нет потребности передавать максимальный размер эскадрильи, аналогично, был убран метод getMaxUnitsCount, смысл которого теперь утерян;

● реализация больше не хранит нулевые указатели для сбитых или выведенных из состава эскадрильи вертолетов, соответственно нет нужды в методе findFreeUnitPosition;

● метод getHelicopter возвращает ссылку на объект-вертолет вместо указателя, поскольку нулевых указателей внутри вектора теперь не хранится;

● аналогично примерам о журнале полета и истории приземлений вертолетов на площадке, проверку индексов при доступе берет на себя вектор;

● реализация метода getJoinedUnitsCount упрощается до запроса количества размещенных элементов внутреннего вектора;

● при добавлении вертолета в эскадрилью его адрес просто помещается в конец вектора;

● при исключении вертолета из состава эскадрильи используется готовый алгоритм метода erase с автоматическим сдвигом, что было возможно в предыдущей реализации, но не привлекало громоздкостью ручного кодирования в явном виде.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]