Поделиться через


event (расширения компонентов C++)

Ключевое слово event объявляет событие, которое представляет собой уведомление зарегистрированным подписчикам (обработчикам событий), о каких-либо ситуациях.

Все среды выполнения

C++/CX поддерживает объявление элемента события или блока события. Элемент события — это сокращенная запись для объявления блока события. По умолчанию элемент события объявляет функции add(), remove() и raise(), которые были объявлены явно в блоке события. Для настройки функций в элементе события, вместо этого объявите блок события и затем переопределите необходимые функции.

Синтаксис

// event data member
modifier event delegate^ event_name;   

// event block
modifier event delegate^ event_name 
{
   modifier return_value add(delegate^ name);
   modifier void remove(delegate^ name);
   modifier void raise(parameters);
}

Параметры

  • modifier
    Модификатор, который можно использовать или в объявлении событий, или в методе доступа к событию. Допустимые значения: static и virtual.

  • delegate
    Делегат, чья сигнатура должна совпадать с обработчиком события.

  • event_name
    Имя события.

  • return_value
    Возвращаемое значение метода доступа к событию. Чтобы быть проверяемым, возвращаемый тип должен быть void.

  • parameters
    (необязательно) Параметры для метода raise, которые соответствуют сигнатуре параметра delegate.

Примечания

События — это ассоциация между делегатом и членом функции (обработчиком события), что отвечает активации события и позволяет клиентам из любого класса регистрировать метод, который соответствует сигнатуре и возвращаемому типу основного делегата.

Существует два типа объявлений событий:

  • член данных событий
    Компилятор автоматически создает хранилище для события в форме члена типа делегата, и создает внутренние члены функции add(), remove() и raise(). Член данных событий должен быть объявлен внутри класса. Возвращаемый тип возвращаемого типа делегата должен соответствовать возвращаемому типу обработчика событий.

  • блок события
    Блок события позволяет явно объявить и настроить поведение методов add(), remove() и raise().

operators+= и operator-= можно использовать для добавления и удаления обработчиков событий, или вызывать методы add() и remove() явным образом.

event — контекстно-зависимое ключевое слово; дополнительные сведения см. в разделе Контекстные ключевые слова (расширения компонентов C++).

Среда выполнения Windows

Примечания

Дополнительные сведения см. в разделе События(C++/CX).

Если планируется добавить, а затем удалить обработчик события, следует сохранить структуру EventRegistrationToken, которую возвращает операция добавления. Затем в операции удаления, необходимо использовать сохраненную структуру EventRegistrationToken, чтобы определить обработчик событий, который необходимо удалить.

Требования

Параметр компилятора: /ZW

Среда CLR

Ключевое слово event позволяет объявить событие. Событие — это способ класса предоставлять уведомления о возникновении каких-либо ситуаций.

Синтаксис

// event data member
modifier event delegate^ event_name; 

// event block
modifier event delegate^ event_name 
{
   modifier return_value add(delegate^ name);
   modifier void remove(delegate^ name);
   modifier void raise(parameters);
}

Параметры

  • modifier
    Модификатор, который можно использовать или в объявлении событий, или в методе доступа к событию. Допустимые значения: static и virtual.

  • delegate
    Делегат, чья сигнатура должна совпадать с обработчиком события.

  • event_name
    Имя события.

  • return_value
    Возвращаемое значение метода доступа к событию. Чтобы быть проверяемым, возвращаемый тип должен быть void.

  • parameters
    (необязательно) Параметры для метода raise, которые соответствуют сигнатуре параметра delegate.

Примечания

События — это ассоциация между делегатом и членом функции (обработчиком события), что отвечает активации события и позволяет клиентам из любого класса регистрировать метод, который соответствует сигнатуре и возвращаемому типу основного делегата.

Делегат может включать один или более связанных методов, которые будут вызываться, когда код указывает, что событие произошло. События одной программы может быть доступно другим программам, ориентированным на среду CLR .NET Framework. Пример см. в разделе Вызов событий, определенных в другой сборке.

Существует два типа объявлений событий:

  • члены данных событий
    Хранилище для события в форме члена типа делегата создается компилятором для событий элемента данных. Член данных событий должен быть объявлен внутри класса. Это также известно как обычное событие (см. пример кода ниже).

  • блоки события
    Блоки события позволяют настраивать поведение методов добавления, удаления и вызова с помощью реализации методов добавления, удаления и вызова. Сигнатура методов добавления, удаления и вызова должна совпадать с сигнатурой делегата. События блока события не являются членами данных, и любое использование их как членов данных вызовет ошибку компилятора. Пример см. в разделе Определение методов доступа к событиям.

Возвращаемый тип обработчика события должен соответствовать возвращаемому типу делегата.

В платформе .NET Framework данные-член можно рассматривать, как если бы это был сам метод (т. е., метод Invoke соответствующего делегата). Необходимо заранее определить тип делегата для объявления данных-члена управляемого события. Напротив, метод управляемого события неявно определяет соответствующий управляемый делегат, если он еще не определен. См. образец кода в конце раздела для примера.

При объявлении управляемого события можно указать методы доступа добавления и удаления, которые будут вызваны в случае добавления или удаления обработчиков события с помощью операторов += и -=. Методы добавления, удаления и вызова можно вызвать явным образом.

Следующие шаги необходимо выполнить для создания и использования событий в Visual C++:

  1. Создайте или определите делегат. Если указать собственное событие, то необходимо убедиться, что есть делегат, который будет использоваться с ключевым словом event. Если событие предопределено, например в платформе .NET Framework, то потребителям события нужно знать только имя делегата.

  2. Создайте класс, который содержит:

    • Событие, созданное из делегата.

    • (необязательно) Метод, который подтверждает, что существует экземпляр делегата, объявленный с ключевым словом event. В противном случае эта логика должна быть помещена в коде, который вызывает событие.

    • Методы, которые вызывают события. Эти методы могут быть переопределениями какой-то функции базового класса.

    Этот класс определяет событие.

  3. Укажите один или несколько классов, которые подключают методы к событию. Каждый из этих классов свяжет один или несколько методов с событием в базовом классе.

  4. Используйте событие:

    • Создайте объект класса, содержащий объявление события.

    • Создайте объект класса, содержащий определение события.

Дополнительные сведения о событиях C++/CLI см. в разделах

Требования

Параметр компилятора: /clr

Примеры

Пример

В следующем примере кода показано объявление пары делегатов, событий и обработчиков событий; подпись (добавление) обработчиков событий; вызов обработчиков событий; и затем отказ от подписки (удаление) обработчиков событий.

// mcppv2_events.cpp
// compile with: /clr
using namespace System;

// declare delegates
delegate void ClickEventHandler(int, double);
delegate void DblClickEventHandler(String^);

// class that defines events
ref class EventSource {
public:
   event ClickEventHandler^ OnClick;   // declare the event OnClick
   event DblClickEventHandler^ OnDblClick;   // declare OnDblClick

   void FireEvents() {
      // raises events
      OnClick(7, 3.14159);
      OnDblClick("Hello");
   }
};

// class that defines methods that will called when event occurs
ref class EventReceiver {
public:
   void OnMyClick(int i, double d) {
      Console::WriteLine("OnClick: {0}, {1}", i, d);
   }

   void OnMyDblClick(String^ str) {
      Console::WriteLine("OnDblClick: {0}", str);
   }
};

int main() {
   EventSource ^ MyEventSource = gcnew EventSource();
   EventReceiver^ MyEventReceiver = gcnew EventReceiver();

   // hook handler to event
   MyEventSource->OnClick += gcnew ClickEventHandler(MyEventReceiver, &EventReceiver::OnMyClick);
   MyEventSource->OnDblClick += gcnew DblClickEventHandler(MyEventReceiver, &EventReceiver::OnMyDblClick);

   // invoke events
   MyEventSource->FireEvents();

   // unhook handler to event
   MyEventSource->OnClick -= gcnew ClickEventHandler(MyEventReceiver, &EventReceiver::OnMyClick);
   MyEventSource->OnDblClick -= gcnew DblClickEventHandler(MyEventReceiver, &EventReceiver::OnMyDblClick);
}

Output

  
  

Пример

В следующем примере кода демонстрируется логика, используемая для создания метода raise тривиального события: Если событие содержит один или несколько подписчиков, вызов метода raise неявно или явно вызывает делегат. Если тип возвращаемого значения делегата не имеет значение void и если нет подписчиков события, то метод raise возвращает значение по умолчанию для типа делегата. При отсутствии подписчиков событий вызов метода raise просто возвращает значение, и исключение не создается. Если тип возвращаемого значения делегата не является void, то возвращается тип делегата.

// trivial_events.cpp
// compile with: /clr /c
using namespace System;
public delegate int Del();
public ref struct C {
   int i;
   event Del^ MyEvent;

   void FireEvent() {
      i = MyEvent();
   }
};

ref struct EventReceiver {
   int OnMyClick() { return 0; }
};

int main() {
   C c;
   c.i = 687;

   c.FireEvent();
   Console::WriteLine(c.i);
   c.i = 688;

   EventReceiver^ MyEventReceiver = gcnew EventReceiver();
   c.MyEvent += gcnew Del(MyEventReceiver, &EventReceiver::OnMyClick);
   Console::WriteLine(c.i);   
}

Output

0

См. также

Основные понятия

Расширения компонентов для платформ среды выполнения