Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
diplomat1129
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 83
14.04.2014, 14:48     Заменить делегаты функциями обратного вызова #1
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));
        }
Мне надо сделать аналог на с++. с делегатами разобрался - их надо заменить функциями обратного вызова..
а вот как быть с событиями. есть ли аналог?или как то же обходятся люди ?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.04.2014, 14:48     Заменить делегаты функциями обратного вызова
Посмотрите здесь:

Метод обратного пузырька(камешка) C++
C++ Функция обратного вызова
оформить решение в виде функции следующими способами: 1. функция расположена после ее вызова; 2. функция расположена после до ее вызова; 3. функ C++
C++ нужно чтобы функция располагалась до ее вызова, после ее вызова и в другом файле. Как это сделать?
C++ Делегаты и события
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6456 / 3830 / 885
Регистрация: 30.01.2014
Сообщений: 6,626
18.04.2014, 18:30     Заменить делегаты функциями обратного вызова #21
Цитата Сообщение от 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;
};
Как видно, это все несколько отличается от того, что предлагает С#, поэтому не учитывать эти особенности при переносе нельзя.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
AceOfSpades
41 / 40 / 3
Регистрация: 14.08.2012
Сообщений: 231
18.04.2014, 19:54     Заменить делегаты функциями обратного вызова #22
Просто мы друг друга не понимаем)) я об одном, вы о другом.
DrOffset
6456 / 3830 / 885
Регистрация: 30.01.2014
Сообщений: 6,626
18.04.2014, 20:31     Заменить делегаты функциями обратного вызова #23
Цитата Сообщение от 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:
Я в первую очередь пишу это здесь не для того, что бы кого-то принизить или уличить в ошибке, а только лишь из соображений корректности ответа. Слишком уж велик шанс неправильно научить человека.
AceOfSpades
41 / 40 / 3
Регистрация: 14.08.2012
Сообщений: 231
18.04.2014, 20:34     Заменить делегаты функциями обратного вызова #24
Да, вы всё правильно говорите, но автор же хотел синтаксис как в шарпе, поэтому так. На плюсах я бы вообще так не делал, есть другие способы и библиотеки для работы с событиями.

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

Цитата Сообщение от DrOffset Посмотреть сообщение
Однако это тоже не будет иметь нужного эффекта. Т.к. может спровоцировать на сравнение с другими указателями, отличными от NULL, хотя этого здесь не требуется.
перегрузка определена только для типов int, поэтому сравнение с указателями вызовет ошибку компиляции.
DrOffset
6456 / 3830 / 885
Регистрация: 30.01.2014
Сообщений: 6,626
18.04.2014, 20:47     Заменить делегаты функциями обратного вызова #25
Цитата Сообщение от AceOfSpades Посмотреть сообщение
перегрузка определена только для типов int, поэтому сравнение с указателями вызовет ошибку компиляции.
Именно это меня и смутило. Я привел две перегрузки с void*, поэтому завел речь про указатели. Это было предложено как пример некорректного выхода из ситуации (с учетом пояснения, что NULL применяется для указателей) - в общем, видимо это не было замечено при чтении моего поста .
Цитата Сообщение от AceOfSpades Посмотреть сообщение
Ошибки нет
Да, согласен, нет.
Цитата Сообщение от AceOfSpades Посмотреть сообщение
но автор же хотел синтаксис как в шарпе
Пусть автор меня поправит, но мне показалось, что он хотел поведение как в C#, а не синтаксис...
AceOfSpades
41 / 40 / 3
Регистрация: 14.08.2012
Сообщений: 231
18.04.2014, 20:56     Заменить делегаты функциями обратного вызова #26
Цитата Сообщение от DrOffset Посмотреть сообщение
Я привел две перегрузки с void*, поэтому завел речь про указатели
Да, не доглядел, сорри
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.04.2014, 23:38     Заменить делегаты функциями обратного вызова
Еще ссылки по теме:

C++ Нейронные сети обратного распространения
C++ Метод обратного распространения ошибки
Метод обратного распространения ошибки C++

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

Или воспользуйтесь поиском по форуму:
diplomat1129
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 83
18.04.2014, 23:38  [ТС]     Заменить делегаты функциями обратного вызова #27
Да, хотел события как в С#, а не синтаксис. Спасибо вам всем )
Yandex
Объявления
18.04.2014, 23:38     Заменить делегаты функциями обратного вызова
Ответ Создать тему
Опции темы

Текущее время: 16:29. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru