Обратные вызовы в C++ | страница 17
> 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.
>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)
> initiator.setup((Executor1*)&executor3, &Executor::callbackHandler1); // (9)
> initiator.setup((Executor1*)&executor3, &Executor::callbackHandler2); // (10)
> initiator.setup((Executor2*)&executor3, &Executor::callbackHandler1); // (11)
> initiator.setup((Executor2*)&executor3, &Executor::callbackHandler2); // (12)
>}
В строках 1 и 2 все прозрачно: какой метод назначен, такой и будет вызван.
В строке 3 мы назначаем указатель на метод Executor::callbackHandler1, но поскольку в классе Executor1 он переопределен, будет вызван метод Executor1::callbackHandler1.
В строке 4 мы назначаем указатель на Executor::callbackHandler2; в классе Executor1 такого метода нет (т.е. он не переопределен), поэтому будет вызван метод базового класса Executor::callbackHandler2.
В строке 5 мы назначаем указатель на Executor::callbackHandler1; в классе Executor2 метод не переопределен, поэтому будет вызван метод базового класса Executor::callbackHandler2.
В строке 6 мы назначаем указатель на Executor::callbackHandler2; в классе Executor2 он переопределен, поэтому будет вызван метод Executor2:: callbackHandler2.
С классом Executor3 ситуация еще интереснее, поскольку он использует множественное наследование