Смекни!
smekni.com

Эффективное использование STL и шаблонов (стр. 3 из 3)

Требования к клиентским приложениям

Требования немногочисленны. Для классов событий и состояний должны быть определены operator==, operator= и конструктор копирования. operator== используется для поиска событий и состояний в списках алгоритмом STL find. operator= используется при копировании элементов списков. Конструктор копирования используется при инициализации списков и других элементов.

Если клиент пользуется предоставленным функтором для вызова функций входа и выхода, то класс состояния должен реализовывать соответствующие функции: OnExit и OnEnter.

Преимущества и недостатки предложенного решения

Преимущества:

Шаблон строго типизирован. Это означает, что неправильно написанный код не будет принят компилятором, и ошибка не дойдет до времени выполнения программы.

Расширены понятия состояния и события. Теперь это произвольные классы, написанные пользователем.

Не используется оператор reinterpret_cast<…>, способный привести к неправильным результатам.

Все описание автомата сосредоточено в одном месте. Нет привязки к последовательности описания реакций на события.

Гибкость поведения определяется пользовательскими функторами. Предоставляется набор уже готовых функторов.

Возможно динамическое создание описания конечного автомата. Например, можно создать экземпляры Proxy-классов, прочитать из файла описание автомата, а затем создать экземпляр SFiniteStateMachine.

Нет операций создания и удаления объектов с помощью операторов new и delete.

Нет никаких требований к классам состояний и событий (кроме возможности их сравнения).

Недостатки:

Много операций копирования при создании автомата. Однако этот недостаток отчасти компенсируется тем, что обычно автомат создается один раз, а используется многократно.

Надо писать две директивы препроцессора или использовать длинный префикс. Однако это лишь проблема набивки текста.

Лично я готов мириться с этим коротким списком недостатков ради полученных преимуществ.

Возможные пути усовершенствования шаблона

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

Можно отказаться от промежуточного класса SFiniteStateMachineProxy. Это позволит сэкономить на копированиях, но внесет потенциальную возможность неправильного использования шаблона.

Можно ввести манипуляторы, которые позволят в явном виде при описании переходов указывать такие, которые надо игнорировать, или генерировать исключение при их появлении.

Потоковая безопасность

В шаблоне используются контейнеры STL, операции с которыми в многопоточной среде могут привести к проблемам. Поскольку при проектировании шаблона ставилась цель разработать независимое от платформы решение, то никаких средств синхронизации в шаблоне нет. Наличие средств синхронизации, как известно, в зависимости от ситуации может быть как достоинством, так и недостатком. Если они не нужны, их наличие только породит дополнительные накладные расходы. Добавить же средства синхронизации в шаблон опытному разработчику не составит труда.

Список литературы

C/C++ User’s Journal, May 2000

Booch G., Rumbaugh J., Jacobson I. The Unified Modeling Language User Guide. Addison-Wesley, 2001

Meyers S. Effective STL. Addison-Wesley, 2001

Alexandrescu A. Modern C++ Design. Addison-Wesley, 2002

Lewis P., Rosenkrantz D., Stearns R. Compiler Design Theory. Addison-Wesley, 1976

Schildt H. С/С++ Programmer’s Reference. Second Edition. Williams, 2000

Meyers S. Effective C++. Second Edition. Addison-Wesley, 1998 and More Effective C++. Addison-Wesley, 1996

Sutter G. Exceptional C++. Addison-Wesley, 2002