Обработка событий в С++

на главную - закладки

Жанры

Поделиться:

Обработка событий в С++

Шрифт:

Введение

Так уж исторически сложилось, что в языке С++ нет событий. Событием (event) является исходящий вызов (программисты на VB хорошо знакомы с ними) и в С++ их действительно нет. Иногда события путают с сообщениями (message), но это не верно. Сообщение это прямой вызов: например windows вызывает оконную процедуру для передачи собщения окну. Объект (система) вызывает функцию обькта(окна). Вызов происходит от объекта к объекту. В отличии от сообщения событие имеет другую механику. Объект инициирует событие и вызываются все объекты-обработчики. Т.е. от одного объекта к нескольким.

Причем объект инициатор события может ничего не «знать» об его обработчиках, поэтому событие называют исходящим вызовом.

Раз уж в С++ события на уровне языка не поддерживаются, значит стоит организовать их на уровне библиотеки. Здесь приведена реализация такой библиотеки. В ней есть два класса signal и slot.

Итак, чтобы сделать какой нибудь класс источником события поместите в него переменную типа signal:

struct EventRaiser { // источник события

 signal<void> someEvent; // void – тип аргумента события

};

А чтобы сделать класс обработчиком поместите в него переменную типа slot, функцию обработчик и свяжите slot с обработчиком:

struct EventHandler { // обработчик события

 slot someHandler; // переходник

 void onEvent(void) {

// функция обработчик события

printf("event handled");

 }

 void connect (EventRaiser& er) {

someHandler.init(er.someEvent, onEvent, this); // установим связь события с обработчиком

 }

};

Так как эти объекты являются частью своих хозяев, не нужно заботится о времени жизни связи. Ее разрыв произойдет во время разрушения одного из них. Событие же инициируется вызвовом метода signal::raise:

struct EventRaiser { // источник события

 signal<void> someEvent; // void – тип аргумента события

 void someFunc {

someEvent.raise; // инициация события

 }

};

Пример

В примере создаются два класса обработчик и инициатор события, устанавливается связь между ними и иллюстрируется обработка события в нескольких объектах одновременно:

#include "stdafx.h"

#include "sigslot.h"

struct EventRaiser {
// источник события

 signal<const char*> event; // const char* – тип аргумента. может быть void

 void raise(const char *eventName) {

printf("raising %s event\n", eventName);

event.raise(eventName);

 }

} g_Raiser; //
глобальный объект

struct EventHandler { // обработчик события

 const char *color;

 slot handler; // переходник

 void onEvent(const char *eventName) { // обработчик события

printf("\t%s event handled in %s object\n", eventName, color);

 }

 EventHandler(const char *clr): color(clr) {

handler.init(g_Raiser.event, onEvent, this); // установим связь

 }

};

int main(int argc, _TCHAR* argv[]) {

 EventHandler red("Red");

 g_Raiser.raise("Small"); // событие обработается в red

 {

{

EventHandler blue("Blue");

g_Raiser.raise("Big"); // событие обработается в red и blue

}

EventHandler green("Green");

g_Raiser.raise("Medium"); // событие обработается в red и green.

// объект blue уничтожен, связь разорвана

 }

 return 0;

}

Краткое описание классов

signal – cобытие (детали реализации опущены)

template <class Arg> // Arg – тип аргумента функции обработчика

class signal {

public:

 // Инициировать событие

 void raise(

Arg arg // Арумент arg будет передан в обработчики события

 );

};

slot – переходник для обработки события в классе-обработчике (детали реализации опущены)

class slot {

public:

 // установить связь с событием и обработчиком

 template <

class Owner, // класс-обработчик

class Arg // Тип аргумента события.

 >

 void init(

signal<Arg>&sig, // событие

void (Owner::*mpfn)(Arg), // функция обработчик

Owner *This // обьект обработчик

12
Комментарии:
Популярные книги

Отморозки

Земляной Андрей Борисович
Фантастика:
научная фантастика
7.00
рейтинг книги
Отморозки

Цеховик. Книга 2. Движение к цели

Ромов Дмитрий
2. Цеховик
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Цеховик. Книга 2. Движение к цели

Гримуар темного лорда V

Грехов Тимофей
5. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда V

Комендант некромантской общаги 2

Леденцовская Анна
2. Мир
Фантастика:
юмористическая фантастика
7.77
рейтинг книги
Комендант некромантской общаги 2

Попаданка в деле, или Ваш любимый доктор

Марей Соня
1. Попаданка в деле, или Ваш любимый доктор
Фантастика:
фэнтези
5.50
рейтинг книги
Попаданка в деле, или Ваш любимый доктор

Ведьмак. Назад в СССР

Подус Игорь
1. Ведьмак. Назад в СССР
Фантастика:
попаданцы
альтернативная история
6.60
рейтинг книги
Ведьмак. Назад в СССР

Здравствуй, 1984-й

Иванов Дмитрий
1. Девяностые
Фантастика:
альтернативная история
6.42
рейтинг книги
Здравствуй, 1984-й

Огромный. Злой. Зеленый

Новикова Татьяна О.
1. Большой. Зеленый... ОРК
Любовные романы:
любовно-фантастические романы
5.40
рейтинг книги
Огромный. Злой. Зеленый

Черный маг императора

Герда Александр
1. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора

Мое ускорение

Иванов Дмитрий
5. Девяностые
Фантастика:
попаданцы
альтернативная история
6.33
рейтинг книги
Мое ускорение

Вечный. Книга IV

Рокотов Алексей
4. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга IV

Я еще князь. Книга XX

Дрейк Сириус
20. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я еще князь. Книга XX

Матабар IV

Клеванский Кирилл Сергеевич
4. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар IV

Лорд Системы

Токсик Саша
1. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
4.00
рейтинг книги
Лорд Системы