Программирование >>  Многопоточная библиотека с принципом минимализма 

1 ... 97 98 99 [ 100 ] 101 102 103 ... 106


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



1 ... 97 98 99 [ 100 ] 101 102 103 ... 106

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика