|
Программирование >> Многопоточная библиотека с принципом минимализма
Класс Executor должен содержать перегруженную фунюдаю-член опЕг-ror(BaseLhs&, BaseRhs&) для обработки ошибок. Функция Executor: :ОпЕггог вызывается классом StaticDispatcher при обнаружении неизвестного типа. Допустим, что классы Rectangle и Ellipse являются потомками класса Shape, а классы Printer и Screen - потомки класса OutputDevice. struct Painter bool Fire(Rectangle&, Printer*); bool Fire(Ellipse&, Printer*); bool Fire(Rectangle&, Screen*); bool Fire(Ellipse*, Screen*); bool onError(Shape&, OutputDevice*); typedef StaticDispatcher < Painter, Shape, TYPELIST 2(Rectangle, Ellipse), OutputDevice, TYPELlST 2(Printer&, Screen), bool > Dispatcher; Класс StaticDispatcher реализует функцию-член Go, получающую параметры, имеющие типы BaseLhs*, BaseRhs* и Executor* соответственно. Вот пример ее использования (в контексте предьщущих определений). Dispatcher disp; Shape* psh = ...; OutputDevice* pDev = ...; bool result = disp.Go(*pSh, *pDev); Классы BasicDispatcher и BasicFastDispatcher реализуют динамические диспетчеры, позволяющие пользователям добавлять обрабатывающие функции в ходе выполнения программы. Класс BasicDispatcher находит обработчик за логарифмическое время. Класс BasicFastDispatcher находит обработчик за постоянное время, однако для этого пользователь должен изменить определения всех классов, вовлеченных в диспетчеризацию. Оба класса имеют одинаковый интерфейс. template < class BaseLhs, class BaseRhs = BaseLhs, typename ResultType = void, typename CallbackType = ResultType (*) (BaseLhs*, BaseRhs*) > class BasicDispatcher; Здесь класс CallbackType является типом объекта, выполняющего диспетчеризацию. Классы BasicDispatcher и BasicFastDispatcher хранят и вызывают объекты этого типа. Все остальные параметры имеют тот же смысл, что и в классе StaticDispatcher. Функции, реализуемые классами BasicDispatcher и BasicFastDispatcher, перечислены в табл. 11.1. Кроме указанных трех основных диспетчеров, в библиотеке Loki определены еще два диспетчера: классы FnDispatcher и FunctorDispatcher. Они используют классы BasicDispatcher и BasicFastDispatcher в качестве стратегий. Классы FnDispatcher и FunctorDispatcher имеют одинаковые объявления. template < class BaseLhs, class BaseRhs = BaseLhs, ResultType = void, template <class To, class From> class CastingPolicy = Dynamiccast template <class, class, class, class> class DispatcherBackend = BasicDispatcher > class FnDispatcher; Здесь классы BaseLhs и BaseRhs - это базовые классы двух иерархий, вовлеченных в двойную диспетчеризацию. Класс ResultType задает тип значения, возвращаемого обратными вызовами и диспетчером. Класс CastingPolicy - это шаблонный класс с двумя параметрами. Он должен реализовывать функцию-член Cast, принимающую ссылку на объект класса From и возвращающую ссылку на объект класса То. Основные реализации классов DynamicCaster и Staticcaster используют операторы dynamic cast и statis cast соответственно. Шаблонный класс DispatcherBackend реализует тот же интерфейс, что и классы BasicDispatcher и BasicFastDispatcher, описанный в табл. 11.1. И класс FnDispatcher, и класс FunctorDispatcher определяют функцию-член Add или основные типы обработчиков. Для класса FnDispatcher основным типом обработчика является класс ResultTypeC*)(BaseLhsS, BaseRhs&). Для класса FunctorDispatcher основным типом обработчика является класс Func-tor<ResultType, TYPELlST 2CBaseLhs&, BaseRhs&)>. Описание класса Functor дано в главе 5. Кроме того, класс FnDispatcher определяет шаблонную функцию, предназначенную для регистрации обратных вызовов. void Add<SomeLhs, SomeRhs, ResultType C*callback)(:someLhs&, SomeRhs&), bool symmetrioC); Если обработчик регистрируется функцией-членом Add, описанной выше, пользователь получает преимущества автоматизированного приведения типов и симметрии. В классе FunctorDispatcher определяется шаблонная функция-член Add. template <class SomeLhs, class SomeRhs, class F> void Add(const F& fun); Класс F может быть одним из типов, получаемых объектом класса Functor (глава 5), включая другую конкретизацию класса Functor. Объект класса F должен допускать выполнение оператора вызова функции с аргументами, имеющими типы BaseLhs& и BaseRhs&, и возвращать значение, тип которого может быть преобразован в тип ResultType. Если обработчик не найден, все механизмы диспетчеризации генерируют исключительную ситуацию, имеющую тип std:: runtime error.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |