Реализация событий на C

#c #events

#c #Мероприятия

Вопрос:

После некоторого поиска в Интернете эффективного способа реализации событий на C я нашел следующие методы

  • Класс интерфейса — Приложения могут переопределять виртуальные функции в производном классе
  • Обычный механизм обратного вызова с использованием указателей на функции
  • Делегирует с помощью Boost.function
  • Сигналы и слоты (как используется в Qt)

Я запутался в преимуществах и недостатках каждого из них и в том, когда использовать что-либо из этого. Какой метод является лучшим и почему? Есть ли какие-либо другие решения, которые лучше перечисленных?

Комментарии:

1. Будьте более конкретны в отношении «событий».

2. Я пытаюсь создать какую-то библиотеку SDK. Библиотека могла бы выдавать события приложениям. Я понимаю, что наличие метода абстрактного класса или обратного вызова — это механизм событий «один к одному». Но делегаты или сигналы могут включать события «один ко многим». Есть какие-либо другие рекомендации по использованию делегатов или сигналов?

Ответ №1:

Черт возьми, я бы проголосовал за сигналы усиления в любой день.

Boost обеспечивает переносимость. Конечно, это прекрасно интегрируется, например, с Boost Asio, Functional, Bind и т.д.

Обновить:

Сигналы 2

В этой документации описывается потокобезопасный вариант исходного Boost.Библиотека сигналов. В интерфейс были внесены некоторые изменения для поддержки потокобезопасности, в основном в отношении автоматического управления соединениями. [….]

Boost обеспечивает переносимость. Конечно, это прекрасно интегрируется, например, с Boost Asio, Functional, Bind и т.д.

boost::signals2::сигнал sig;

 sig.connect(amp;print_sum);
sig.connect(amp;print_product);
sig.connect(amp;print_difference);
sig.connect(amp;print_quotient);

sig(5., 3.);
  

Эта программа выведет следующее:

 The sum is 8
The product is 15
The difference is 2
The quotient is 1.66667
  

примеры действий:

 void print_sum(float x, float y)
{
  std::cout << "The sum is " << x y << std::endl;
}

void print_product(float x, float y)
{
  std::cout << "The product is " << x*y << std::endl;
}

void print_difference(float x, float y)
{
  std::cout << "The difference is " << x-y << std::endl;
}

void print_quotient(float x, float y)
{
  std::cout << "The quotient is " << x/y << std::endl;
}
  

Комментарии:

1. Зачем повышать. Сигналы, а не ускорение. Signals2 ?

2. @ildjam: понятия не имею 🙂 обновляю ответ

3. @sehe : Вы смотрели на libtscb ? Его производительность особенно интересна…

4. @ildjam: нет, я ценю совет. Посмотрим на это как-нибудь в эти выходные 🙂

5. Библиотеки boost нет, поскольку я запускаю программу на встроенной платформе. Какова альтернатива?

Ответ №2:

Вы проверили библиотеку GBL? В нем есть все возможности, которые вам могут понадобиться (и, возможно, даже больше) для равномерного проектирования. С его помощью можно создавать (реальные) временные и несвоевременные модели. Это чистый C , не загрязненный макросами. Он также использует C 0x для повышения производительности. Также, если вы используете компилятор C 0x, вы получаете лямбда-функции, работающие как обработчики событий — это очень мощно. GBL поддерживает синхронные и асинхронные обработчики событий, потоки и волокна. Он абстрагирует поток событий через сигналы и порты. При некоторой изобретательности и тщательном проектировании вы можете использовать асинхронные обработчики событий и значительно повысить производительность в многоядерных / многопроцессорных системах. В нем также есть графический конструктор и трассировщик.

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

Ответ №3:

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

Два других варианта требуют использования boost и Qt соответственно.

Преимущества / недостатки — это своего рода слишком широкий вопрос, и ответ на него во многом зависит от того, что вы делаете, в какой среде и с какой целью.

Ответ №4:

Вы можете использовать шаблон проектирования Observer. Вот пример его исходного кода на C . http://sourcemaking.com/design_patterns/observer/cpp/3