Оценить:
 Рейтинг: 0

Обратные вызовы в C++

Год написания книги
2021
<< 1 ... 4 5 6 7 8 9 10 11 12 13 >>
На страницу:
8 из 13
Настройки чтения
Размер шрифта
Высота строк
Поля

};

int main()                                                 // (3)

{

Initiator initiator;                                     // (4)

Executor executor;                                       // (5)

initiator.setup(&executor, &Executor::callbackHandler);  // (6)

initiator.run();                                         // (7)

}

В строке 1 объявляется класс-исполнитель. В строке 2 объявлен метод класса, который будет выполнять функцию обработчика обратного вызова. В указанный метод передается информация вызова (в нашем случае это eventID). В строке 3 объявлена основная функция, в которой осуществляются все необходимые операции. В строке 4 объявлен класс-инициатор, в строке 5 объявлен класс-исполнитель. В строке 6 осуществляется настройка обратного вызова, в строке 7 производится запуск инициатора.

2.3.4. Управление контекстом

Рассматриваемая реализация позволяет осуществлять управление контекстом тремя способами: настройка экземпляра класса-исполнителя, настройка указателя на метод, переопределение виртуальных функций. Это приводит к интересным эффектам.

Пусть у нас будут объявления классов-исполнителей с наследованием, как показано в Листинг 12. Графически иерархия наследования изображена на Рис. 13.

Листинг 12. Классы-исполнители с наследованием

class Executor

{

public:

virtual void callbackHandler1(int eventID);

virtual void callbackHandler2(int eventID);

};

class Executor1: public Executor

{

public:

void callbackHandler1(int eventID) override;

};

class Executor2: public Executor

{

public:

void callbackHandler2(int eventID) override;

};

class Executor3: public Executor1, public Executor2

{

};

Рис. 13. Иерархия наследования классов-исполнителей.

Итак, будем назначать различные указатели на экземпляры классов и методы-члены, как показано в Листинг 13.

Листинг 13. Настройка указателей на классы и методы

int main()

{

Initiator initiator;

Executor  executor;

Executor1 executor1;

Executor2 executor2;

Executor3 executor3;

initiator.setup(&executor, &Executor::callbackHandler1);   // (1)

initiator.setup(&executor, &Executor::callbackHandler2);   // (2)

initiator.setup(&executor1, &Executor::callbackHandler1);  // (3)

initiator.setup(&executor1, &Executor::callbackHandler2);  // (4)

initiator.setup(&executor2, &Executor::callbackHandler1);  // (5)

initiator.setup(&executor2, &Executor::callbackHandler2);  // (6)

//initiator.setup(&executor3, &Executor::callbackHandler1); //Incorrect, base class is ambiguous  // (7)

//initiator.setup(&executor3, &Executor::callbackHandler2); //Incorrect, base class is ambiguous  // (8)
<< 1 ... 4 5 6 7 8 9 10 11 12 13 >>
На страницу:
8 из 13