0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 86
|
||||||
1 | ||||||
Заменить делегаты функциями обратного вызова14.04.2014, 14:48. Показов 2230. Ответов 26
Метки нет (Все метки)
а вот как быть с событиями. есть ли аналог?или как то же обходятся люди ?
0
|
14.04.2014, 14:48 | |
Ответы с готовыми решениями:
26
Функция обратного вызова Стрелка в описании функции обратного вызова Передача функций обратного вызова как членов некоторого класса Почему callback-функции называются функциями ОБРАТНОГО вызова |
54 / 53 / 5
Регистрация: 14.08.2012
Сообщений: 252
|
|
14.04.2014, 20:13 | 2 |
Сообщение было отмечено diplomat1129 как решение
Решение
Делается довольно несложно. Проект прилагаю.
Класс EventHandler реализует работу по подписке/отписке и вызову обработчиков события. Весь остальной код, предполагается, что пишет пользователь, и использует "библиотечный" EventHandler для определения своих событий. Единственное ограничение: обработчики событий должны быть определены вне класса (а если им требуется доступ к внутренностям класса, то просто объявить их друзьями). Хотя, ничего плохого в этом не вижу, наоборот, код структурируется.
1
|
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 86
|
|
17.04.2014, 19:22 [ТС] | 3 |
Ошибка почему-то.когда использую ваш заголовочный файл
0
|
54 / 53 / 5
Регистрация: 14.08.2012
Сообщений: 252
|
|
17.04.2014, 19:25 | 4 |
Какая?
0
|
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 86
|
||||||
17.04.2014, 19:32 [ТС] | 5 | |||||
0
|
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
|
||||||
17.04.2014, 19:42 | 6 | |||||
Сообщение было отмечено diplomat1129 как решение
Решение
diplomat1129,
Там ошибка. Связанная с тем, что VC++ не требует наличия ключевого слова typename в этой ситуации (это объясняется отсутствием в VC++ two-phase name lookup, но это тянет на отдельную тему), хотя по стандарту оно должно быть. В общем, надо так:
1
|
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 86
|
||||||
17.04.2014, 19:46 [ТС] | 7 | |||||
0
|
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
|
|
17.04.2014, 19:48 | 8 |
diplomat1129, Насчет этого наверное лучше у автора спросить. Но мне кажется, что можно просто заменить на ноль.
1
|
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 86
|
||||||
17.04.2014, 20:13 [ТС] | 9 | |||||
Начал использовать события
In file included from NMClient.cpp:14:0, from main.cpp:1: EventHandler.h: In instantiation of ‘void EventHandler<EventArgs>::operator()(void*, EventArgs*) [with EventArgs = EventMsgArgs]’: NMClient.cpp:50:40: required from here EventHandler.h:34:81: error: ‘class std::list<void (*)(void*, EventMsgArgs*), std::allocator<void (*)(void*, EventMsgArgs*)> >’ has no member named ‘cbegin’ for (typename list<CallBackFunction>::const_iterator it = callBackList.cbegin(); it != callBackList.cend(); it++) ^ EventHandler.h:34:87: error: ‘class std::list<void (*)(void*, EventMsgArgs*), std::allocator<void (*)(void*, EventMsgArgs*)> >’ has no member named ‘cend’ for (typename list<CallBackFunction>::const_iterator it = callBackList.cbegin(); it != callBackList.cend(); it++) если не использовать в другом классе, а просто компилить, то компилиться без ошибок
0
|
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
|
|
17.04.2014, 20:18 | 10 |
diplomat1129, C++11 нужно, чтобы это работало. -std=c++11
0
|
54 / 53 / 5
Регистрация: 14.08.2012
Сообщений: 252
|
|
17.04.2014, 22:41 | 11 |
Всё это возможно из-за того, что я не учитывал особенности VC++ и C++11, т.к. первый категорически не перевариваю (из-за личных взглядов), а для второго у меня нет поддержки компилятора.
Изначально я создавал проект для этого файла как обычный Win32 без всяких там .net и clr. Среда разработки VS2010. По поводу этих ошибок сказать трудно, что компилятору не нравится, может нет нужных зависимостей, иначе почему он ругается на отсутствие вполне стандартного члена библиотеки.
0
|
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
|
|
17.04.2014, 22:49 | 12 |
Этот метод появился только в С++11. Возможно в VS2010 уже были реализованы некоторые фичи заранее.
Автор, ИМХО, собирает проект в каком-то GCC. Ключевое слово typename не обязательно в той ситуации в VS2010 (как и в любой другой студии) исходя из отсутствия реализации в компиляторе two-phase name lookup. Некоторые считают, что это хорошо, однако подобный код все-таки остается нестандартным. И GCC вполне обоснованно его не собирает.
0
|
54 / 53 / 5
Регистрация: 14.08.2012
Сообщений: 252
|
|
17.04.2014, 23:21 | 13 |
0
|
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
|
|
17.04.2014, 23:36 | 14 |
AceOfSpades, выше я уже показывал как
1
|
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 86
|
|||||||||||
18.04.2014, 10:05 [ТС] | 15 | ||||||||||
События сделал. ВОт например
в main
main.cpp:5:25: error: ‘ClientEventArgs’ has not been declared In file included from main.cpp:1:0: NMClient.cpp: In function ‘int main()’: NMClient.cpp:67:26: error: ‘EventHandler<EventArgs> NMClient::OnStop’ is private main.cpp:10:10: error: within this context main.cpp:10:20: error: invalid conversion from ‘void (*)(void*, int*)’ to ‘EventHandler<EventArgs>::CallBackFunction {aka void (*)(void*, EventArgs*)}’ [-fpermissive] In file included from NMClient.cpp:14:0, from main.cpp:1: EventHandler.h:18:30: error: initializing argument 1 of ‘EventHandler<EventArgs>& EventHandler<EventArgs>::operator+=(EventHandler<EventArgs>::CallBackFunction) [with EventArgs = EventArgs; EventHandler<EventArgs> = EventHandler<EventArgs>; EventHandler<EventArgs>::CallBackFunction = void (*)(void*, EventArgs*)]’ [-fpermissive]
0
|
54 / 53 / 5
Регистрация: 14.08.2012
Сообщений: 252
|
|
18.04.2014, 10:22 | 16 |
Типы параметров не совпадают. В вашем методе тип ClientEventArgs, а в классе определен хэндлер с типом EventArgs. Либо приводите тип, либо хэндлер объявите тоже с типом ClientEventArgs.
И ошибки: ClientEventArgs - не объявлен (может инклуд забыли?) OnStop - объявите публичным, иначе он не виден снаружи класса Добавлено через 11 минут Правила создания событий лучше делать такие: Имя события - что-то случилось, в вашем случае Stopped. Метод, вызывающий событие - защищенный виртуальный с приставкой On, в вашем случае protected: virtual void OnStopped(); И всё-таки не с нулем лучше сравнивать, а с NULL (null), если он у вас не определен, то добавьте перед описанием класса #define null 0 Это общепринятый стиль в C#, раз уж вы его в С++ решили перетащить.
1
|
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
|
||||||
18.04.2014, 15:05 | 17 | |||||
Все-таки лучше так не делать. NULL определен, но он используется для указателей, а в современном языке его лучше вообще не использовать, вместо него уже есть стандартный nullptr. Если очень хочется именно null, то лучше константу объявить.
0
|
54 / 53 / 5
Регистрация: 14.08.2012
Сообщений: 252
|
|
18.04.2014, 16:19 | 18 |
Речь же шла о подобии в C#, а там все ссылочные типы (классы и указатели) могут быть null.
static const int null = 0; - если больше нигде не нужно использовать null в других файлах, то можно. Чем #define хуже? Мы же определяем новую семантику для типа, а не переменную.
0
|
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
|
||||||
18.04.2014, 16:50 | 19 | |||||
Речь шла о портировании на С++, а это разные вещи. В каждом языке есть свои нюансы, и их надо учитывать. Вслепую копировать подходы из одного языка в другой - неправильно.
Вот в этом коде нет ссылочных типов. И здесь мы сравниваем значение а с NULL, а не ссылку на а с NULL. Поэтому, если не имелось в виду сравнение с нулем, то в С++ этот код бессмысленный.
Препроцессор ничего не знает про типы. Это такая автоматизированная автозамена.
0
|
54 / 53 / 5
Регистрация: 14.08.2012
Сообщений: 252
|
|
18.04.2014, 17:34 | 20 |
При чём тут препроцессор? Это его проблемы, что он не знает про типы, но человек же знает. Поэтому макроподстановки и полезны, делают язык более гибким.
Выражение OnStop != 0 для меня, например означает, что OnStop имеет семантику значения (хотя в данном случае это не так), что вызывает дискомфорт или даже путаницу (почему бы тогда не сравнивать с 1, 2 ...). Выражение OnStop != null (уже ясно дает понять, что речь идет прежде всего о типе (неважно, указатель это или что-то другое). Хотя формальной разницы тут нет. Объявление null как константы опять же вносит семантику значения... В общем не буду больше с вами спорить.
0
|
18.04.2014, 17:34 | |
18.04.2014, 17:34 | |
Помогаю со студенческими работами здесь
20
Функция обратного вызова Процедура обратного вызова Функция обратного вызова Функция обратного вызова Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |