Разработка программного модуля для компьютерной игры

Дипломная работа - Компьютеры, программирование

Другие дипломы по предмету Компьютеры, программирование



такое метапрограммирование является вариантом умных макроподстановок. С одной стороны, это увеличивает объем компилируемого кода (часто в разы), но с другой, дает очень большую гибкость в использовании.

Перед макросами с параметрами препроцессора языка C (которые сохраняют в полном объёме свой функционал и в C++) шаблоны имеют следующие преимущества:

)область видимости шаблонов подчиняется стандартным правилам языка C++, в то время как макрос всегда является объектом с глобальной видимостью;

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

)препроцессор рассматривает параметры макроса как текстовые строки без дополнительных проверок; это может привести к замаскированным ошибкам; параметры шаблона по использованию во многом аналогичны параметрам функции.

В качестве иллюстрации, рассмотрим довольно распространенным пример использования макроса и шаблона для определения возведения в квадрат (листинг 2.1). Легко видеть, что оба подхода позволяют определить функцию возведения в квадрат, однако использование шаблона позволяет избежать нежелательного многократного выполнения операций с побочным эффектом (в примере - двукратного выполнения операции инкремента). Замечу, что для шаблонных функций аргумент шаблона может быть вычислен из типа переданного аргумента, что во многих случаях позволяет избежать явного указания аргументов шаблона.

Листинг 2.1. Макрос и шаблон

#define SQR(x) ((x) * (x))

template T sqr(const T& x) { return (x * x); }test()

{x = 2;y = 2;= sqr(y);= SQR(x);= sqr(++y);= SQR(++x);// ошибка! Инкремент x произойдет дважды.

}

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

2.2.2 Контейнеры STL

Контейнеры STL - это шаблонные классы, которые предназначены для хранения ряда однотипных объектов. К объектам, хранимым в контейнере, предъявляются следующие требования:

) доступный конструктор копирования;

) доступный оператор присваивания;

) доступный деструктор.

Все контейнеры поддерживают базовый функционал:

) набор конструкторов; среди них: конструктор по умолчанию, конструктор копирования, конструктор, заполняющий контейнер элементами из последовательности и ряд других;

) деструктор; при уничтожении контейнера вызываются деструкторы всех содержащихся в нём объектов, а всё память освобождается;

) функции begin(), end(), rbegin(), rend() - возвращают итераторы на начало и конец последовательности объектов, содержащихся в контейнере, в прямом и, соответственно, обратном порядке; как и всюду в STL, итератор на начало указывает на первый элемент последовательности, а итератор на конец - на место в памяти за последним;

) функция size(), возвращающая количество элементов в контейнере.

В разработке VFS контейнеры применялись как основной способ хранения данных. Все предоставляемые интерфейсом модуля последовательности объектов являются контейнерами STL. Ниже перечислены основные использовавшиеся контейнеры.

vector - контейнер, являющийся динамическим массивом. Используется для организации редко редактируемых списков. Контейнер vector эффективно реализует следующие операции:

) добавление и удаление элементов в конце массива;

) доступ к элементу с произвольным номером;

) возможность интерпретировать список элементов как традиционный массив C.

При этом добавление или удаление элемента в середине может привести к значительным накладным расходам: поскольку стандарт С++ требует, чтобы данные вектора были размещены в памяти непрерывно (как массив С), операции с серединой контейнера вызовут переаллокацию памяти.

Доступ к элементам контейнера реализуется с помощью random-access итераторов и оператора [] (аналогично массивам С).

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

Список целесообразно применять в случаях, когда требуются многочисленные операции вставки и удаления в середине контейнера, и нет необходимости в доступе по индексу. Этот контейнер поддерживает очень быстрые операции слияния и разделения списков (физического копирования элементов при этом не происходит, модифицируются только указатели в управляющих структурах)., multiset, map, multimap - ассоциативные контейнеры, предназначенные для хранения упорядоченных последовательностей элементов с возможностью быстрой вставки и удаления.

По затратам памяти и отношению к указателям ассоциативные контейнеры похожи на list (в большинстве реализаций для представления этих контейнеров используются бинарные деревья). Не стоит использовать эти контейнеры, если в этом нет необходимости.

Контейнеры с приставкой multi- допускают повторяющиеся элеметы, без приставки - нет. При этом set требует, чтобы были упорядочены сами хранимые элементы, а map хранит пары ключ-значение (map использует простой вспомогательный шаблон pair для хранения этих пар). Следует учесть, что ассоциативные контейнеры не допускают изменение ключей после добавления элементов. Это правило можно обойти, но это может