#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