Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 86

Заменить делегаты функциями обратного вызова

14.04.2014, 14:48. Показов 3102. Ответов 26
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 public event EventHandler<EventClientArgs> OnNewClient;
        /// <summary>
        /// Обработка добавления нового клиента - процедура синхронизируется с потоком Control и вызывается событие
        /// </summary>
        /// <param name="Id">Адрес клиента</param>
        /// <param name="Name">Имя клиента</param>
        private void NewClientEvent(int Id, string Name)
        {
            /*if ((Control != null) && Control.InvokeRequired)
            {
                DelegateChangeClientEvent Ev = new DelegateChangeClientEvent(NewClientEvent);
                Control.Invoke(Ev, Id, Name);
            }
            else*/
                if (OnNewClient != null)
                    OnNewClient(this, new EventClientArgs(Id, Name));
        }
Мне надо сделать аналог на с++. с делегатами разобрался - их надо заменить функциями обратного вызова..
а вот как быть с событиями. есть ли аналог?или как то же обходятся люди ?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.04.2014, 14:48
Ответы с готовыми решениями:

Функция обратного вызова
#undef UNICODE #include &lt;windows.h&gt; #include &quot;resource.h&quot; #include &lt;iostream&gt; #include &lt;fstream&gt; using namespace std; HWND...

Стрелка в описании функции обратного вызова
#include &lt;iostream&gt; #include &lt;algorithm&gt; std::string s = &quot;hello&quot;; auto end = std::unique(s.begin(), s.end(), (char a, char b) -&gt; bool...

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

26
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
18.04.2014, 18:30
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от AceOfSpades Посмотреть сообщение
При чём тут препроцессор?
В С++ не принято использовать препроцессор для таких вещей.

Цитата Сообщение от AceOfSpades Посмотреть сообщение
Объявление null как константы опять же вносит семантику значения...
Чтобы мы тут не написали (хоть define, хоть что), семантика значения всегда будет. Потому что переменная `а` в примере выше - это значение, а не ссылка.

Цитата Сообщение от AceOfSpades Посмотреть сообщение
В общем не буду больше с вами спорить.
Смысл спорить? Я говорю о том, что нельзя просто брать и перекладывать правила написания кода с С# на С++, потому что многие вещи в С++ отличаются.

AceOfSpades, в общем тут понятно, что у вас есть определенные знания С# и С++, но очевидно, что знание С# выше. Поэтому я хочу пояснить насчет значений и ссылок, и проверок на NULL в С++.
Вот для примера такой код на С++. В комментариях объясню чем отличаются эти методы.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class A
{
public:
    // Здесь а имеет семантику значения, `а` располагается на стеке и `а` копируется при вызове operator==.
    // Поэтому, в данной ситуации, проверку на NULL делать не 
    // нужно (мы не сможем, даже если захотим, записать ее так, 
    // чтобы сохранить требуемую семантику).`а` - это значение.
    bool operator==(A a) const
    {
        return a.value == value;
    }
    // Здесь `а`, как ни странно, тоже имеет семантику значения, И проверку на NULL делать тоже не нужно. 
    // Ссылка в С++ имеет семантику значения (не может быть NULL -
    // это гарантируется языком).
    // Все операции, производимые над ссылкой, на самом деле будут произведены над объектом, 
    // на который она ссылается. В то же время копирования аргумента не произойдет, 
    // как в первом случае, потому что ссылка также имеет и свойства указателя.
    bool operator==(A const & a) const
    {
        return a.value == value;
    }
    // В этой ситуации мы делаем проверку на NULL, потому что `a` - это указатель. Он может содержать NULL, 
    // но может содержать и адрес реального объекта
    bool operator==(A const * a) const
    {
        return a != NULL && a->value == value;
    }
 
private:
    int value;
};
Как видно, это все несколько отличается от того, что предлагает С#, поэтому не учитывать эти особенности при переносе нельзя.
0
54 / 53 / 5
Регистрация: 14.08.2012
Сообщений: 252
18.04.2014, 19:54
Просто мы друг друга не понимаем)) я об одном, вы о другом.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
18.04.2014, 20:31
Цитата Сообщение от AceOfSpades Посмотреть сообщение
Просто мы друг друга не понимаем)) я об одном, вы о другом.
Возможно.
Я сейчас просмотрел еще раз ваш код и вопросы автора. Если я правильно понял, то данные операторы
C++
1
2
inline bool operator==(int a) { return (a == NULL) && (callBackList.size() == 0); }
inline bool operator!=(int a) { return (a == NULL) && (callBackList.size() != 0); }
Нужны для того, что бы работала данная проверка?
C++
1
2
3
4
void StopEvent(){
    if (OnStop != NULL)
        OnStop(this, new EventArgs());
}
Все что, что я говорил выше верно для этого случая. В С++ не принято так делать, этот код запутает плюсовика, как запутал сейчас меня. NULL, как я объяснял выше, применяется для указателей. Очевидно, что, здесь никаких указателей нет. Поэтому, нужно либо изменить операторы следующим образом (кстати, нет ли тут ошибки, в обоих операторах сравнение с NULL и &&, но этого вопроса я сейчас не касаюсь):
C++
1
2
inline bool operator==(void * a) { return (a == NULL) && (callBackList.size() == 0); }
inline bool operator!=(void * a) { return (a == NULL) && (callBackList.size() != 0); }
Однако это тоже не будет иметь нужного эффекта. Т.к. может спровоцировать на сравнение с другими указателями, отличными от NULL, хотя этого здесь не требуется.
Поэтому очевидным и правильным с т.з. программирования на С++, но в то же время идеологически будет соответствовать смыслу, который он несет в С#, будет такой оператор вместо двух вышеприведенных:
C++
1
inline operator bool() const { return callBackList.size() != 0; }
Соответственно проверка будет выглядеть так:
C++
1
2
3
4
void StopEvent() {
     if(OnStop)
         OnStop(this, new EventArgs());
}
Добавлено через 7 минут
addition:
Я в первую очередь пишу это здесь не для того, что бы кого-то принизить или уличить в ошибке, а только лишь из соображений корректности ответа. Слишком уж велик шанс неправильно научить человека.
0
54 / 53 / 5
Регистрация: 14.08.2012
Сообщений: 252
18.04.2014, 20:34
Да, вы всё правильно говорите, но автор же хотел синтаксис как в шарпе, поэтому так. На плюсах я бы вообще так не делал, есть другие способы и библиотеки для работы с событиями.

Цитата Сообщение от DrOffset Посмотреть сообщение
кстати, нет ли тут ошибки, в обоих операторах сравнение с NULL и &&, но этого вопроса я сейчас не касаюсь
Ошибки нет.

Цитата Сообщение от DrOffset Посмотреть сообщение
Однако это тоже не будет иметь нужного эффекта. Т.к. может спровоцировать на сравнение с другими указателями, отличными от NULL, хотя этого здесь не требуется.
перегрузка определена только для типов int, поэтому сравнение с указателями вызовет ошибку компиляции.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
18.04.2014, 20:47
Цитата Сообщение от AceOfSpades Посмотреть сообщение
перегрузка определена только для типов int, поэтому сравнение с указателями вызовет ошибку компиляции.
Именно это меня и смутило. Я привел две перегрузки с void*, поэтому завел речь про указатели. Это было предложено как пример некорректного выхода из ситуации (с учетом пояснения, что NULL применяется для указателей) - в общем, видимо это не было замечено при чтении моего поста .
Цитата Сообщение от AceOfSpades Посмотреть сообщение
Ошибки нет
Да, согласен, нет.
Цитата Сообщение от AceOfSpades Посмотреть сообщение
но автор же хотел синтаксис как в шарпе
Пусть автор меня поправит, но мне показалось, что он хотел поведение как в C#, а не синтаксис...
0
54 / 53 / 5
Регистрация: 14.08.2012
Сообщений: 252
18.04.2014, 20:56
Цитата Сообщение от DrOffset Посмотреть сообщение
Я привел две перегрузки с void*, поэтому завел речь про указатели
Да, не доглядел, сорри
0
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 86
18.04.2014, 23:38  [ТС]
Да, хотел события как в С#, а не синтаксис. Спасибо вам всем )
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.04.2014, 23:38

Почему callback-функции называются функциями ОБРАТНОГО вызова
Доброго времени. Нуждаюсь в объяснении. Очередной вопрос в стиле «Что такое callback-функции и зачем они нужны». Я уже перечитал...

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

Процедура обратного вызова
Немного запутался в процедурах обратного вызова, в процедурных типах. Есть DLL и описание к ней. ... type TFullCardInfo =...

Функция обратного вызова
Функция обратного вызова это та, которая передаётся в качестве аргумента другой функции и внутри неё вызывается. А вот функция,...

Функция обратного вызова
Доброго времени суток уважаемые гуру программирования! Нужна помощь! В описании к DLL есть функция: function...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Новые блоги и статьи
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
Генератор паролей (вариант №2)
Maks 30.10.2026
Обновленная версия ранее созданной обработки. Добавлены следующие реквизиты типа Булево: - Буквы; - Цифры; - Символы. Изменена логика команды "Сгенерировать" и процедуры "ПриОткрытии":. . .
Генератор паролей (вариант №1)
Maks 29.10.2026
Реализация из решения ниже выполнена исключительно по моей инициативе, дабы облегчить себе работу в создании паролей для администрируемых мною сервисов и пользователей. Самым главным критерием для. . .
Установка ChatGPT (Codex) на Windows без использования Microsoft Store
Fabien159 28.10.2026
Здравствуйте всем читающим! Опишу процесс установки ChatGPT (Codex) на Windows, если по каким-то причинам у вас не получается устанавить его через Microsoft Store. И так: 1. Скачиваем с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru