Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 [ 99 ] 100 101 102 103 104 105

Класс 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.



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 [ 99 ] 100 101 102 103 104 105