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

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

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



?й объектно-ориентированный подход, названный потоки (streams).

Центральным понятием библиотеки iostream является поток (stream). Поток можно представить себе как источник и/или приёмник последовательности байт. Переопределяя операции записи и чтения потока (сдвиг), можно заставить поток быть источником и/или приёмником объектов некого класса.

Примечательно, что несмотря на большую гибкость, базовый интерфейс всех потоков предельно прост: он включает в себя возможность последовательно читать байты данных (для потоков ввода istream) и последовательно записывать их (для потоков вывода ostream). При этом для потоков допускается буферизованный вывод (т.е. ситуация, когда оправленные на вывод данные временно хранятся в некотором буфере). Для незамедлительной отправки данных все потоки вывода поддерживают метод flush. Подобная универсальность выгодно отличает библиотеку iostream от альтернативных решений.

Использование потоков ввода/вывода распадается на две стадии: формирование и закрытие потока и собственно ввод/вывод.

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

) тип потока (ввода, вывода, ввода/вывода);

) тип символов потока;

) наличие или отсутствие буферизации;

Замечу, что упомянутые операторы осуществляют форматированный ввод/вывод. Используя такие низкоуровневые средства, как методы put, write, get, read и им подобные, можно посимвольно манипулировать потоками, но эти возможности, как правило, используются при написании высокоптимизированного кода.

В модуле VFS потоки были использованы как одна из основных составных частей: согласно ТЗ, модуль обязан предоставлять данные любого файла как поток. Используя стандартные интерфейсы потоков STL и их буферов, были реализованы потоки, осуществляющие архивирование/распаковку и шифрацию/дешифрацию на лету.

2.2.5 Умные указатели

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

Библиотека STL, предоставляя мощные средства управления памятью, тем не менее не избавляет программиста от возможных ошибок. Частая ошибка - возврат адреса локальной переменной - контролируется только компилятором. Широкое использование механизма исключений и вообще, любой развитый механизм обработки ошибок, требует, чтобы все динамические объекты удалялись вовремя.

Как известно, деструктор локального объекта всегда вызывается в конце области видимости, независимо от причины, по которой объект эту область видимость покинул. Аналогично, компилятор гарантирует, что деструктор члена класса всегда будет вызван при уничтожении объекта. Возникает идея поручить компилятору, посредством классов-обёрток, автоматически отслеживать время жизни динамических объектов. Классы, ведущие себя как указатели на объект и реализующие такое отслеживание принято называть умными указателями (smart pointers).

Рассмотрим использованные при разработке проекта умные указатели. Это шаблон auto_prt из стандартной библиотеки языка C++ и шаблоны weak_prt и shared_prt из библиотеки boost.

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

Шаблон auto_ptr подходит в тех случаях, когда в каждый момент времени у объекта имеется только один владелец. В большинстве реализаций auto_ptr представляет собой класс, в деструкторе которого происходит вызов delete() для указателя, переданного в конструктор. Кроме того, в auto_ptr есть битовый флаг, показывающий, принадлежит ли данному экземпляру auto_ptr право удаления объекта - при копировании auto_ptr флаг выставляется в истину у вновь создаваемого, и в ложь у старого auto_ptr; согласно этому флагу в деструкторе вызывается или не вызывается деструктор для хранимого указателя.

Шаблоны weak_ptr и shared_ptr библиотеки boost являются довольно мощными реализациями указателей с подсчетом ссылок. Поскольку их применение в VFS было эпизодическим, а в конечной версии исключено за ненадобностью, подробно рассматриваться здесь они не будут.

При все своей элегантности и полезности, умные указатели не решают проблему окончательно. Основные источники ошибок следующие:

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

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

2.3 Специализированный инструментарий

Разработка VFS, кроме решения архитектурных задач, потребовала работы над задачами прикладными, такими как шифрование, архивирование и работа с ресурсами исполняемых фалов win32.

2.3.1 Средства работы с зип-архивами

В качеств