Читаем Обработка событий в С++ полностью

Александр Клюев

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

Введение

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

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

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

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

 signal 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 someEvent; // void – тип аргумента события

 void someFunc() {

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

 }

};

Пример

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

#include "stdafx.h"

#include "sigslot.h"


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

 signal 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 // Arg – тип аргумента функции обработчика

class signal {

public:

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

 void raise(

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

 );

};

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

Перейти на страницу:

Похожие книги

C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

Программирование, программы, базы данных