Accountant cpp реализация обработки событий на c


Обработка событий (C++)

Скорее всего тема старая и многократно обсужденная, но я ни поиском ни пролистыванием, таких топиков не нашел.
Речь идет о том, как наиболее красиво получать управление в обработчик событий от элементов управления.
Элементы управления собственные и ничего с Windows не имеющие кроме общего DX :-)
Итак, есть класс, который должен получать управление при изменении например EDIT’a.
Т.е. есть:

P.S.: Здесь можно сделать комплимент Делфи, в нем это сделать, как два байта переслать :-)

Ну если брать тот же дельфи то там у всех контролов есть указатель на владельца, можно также сделать, тогда с вызовом проблем не будет.

fr
Я вообще под SomeMethodThatHaveEvent_OnEditChange подразумевал метод, который может называться как угодно и не обязательно мне необходимо от контрола получать все его события.
Например в этом диалоге меня интересует событие «изменение текста», а в другом диалоге меня интересует «нажатие на кнопку» при установленном на контрол фокусе.
Хотелось бы под любые интересующие события контрола мочь подставлять свои обработчики.
Идеальной конструкцией было бы нечто типа:

используй функторы. посмотри на ргде есть неплохая реализация

crazy25
Может функторы? Их идея в том, чтобы завести класс с виртуальной функцией, а в самой программе хранить экземпляры его потомков, у которых эта виртуальная функция переопределена и делает то, что необходимо (в данном случае в ней вызываются методы других классов)

_Winnie
Спасибо, вариант интересный, буду пробовать.
А boost мне не подуше. наверное еще я до него не дорос.

Но вот уж поистине, как все страшно :-)
Такой мощный язык (C++), с такими возможностями и такой бредовой проблемой на ровном месте.
А проблема-то концептуальная, как недодумка выглядит (привет Страуструпу и комитету).
Отчего на уровне языка не разруливать передачу адреса метода класса?
Ведь даже если метод не static он своего адреса в памяти не меняет!
Да пусть передается еще и адрес объекта класса, в котором этот метод лежит.
Наверное я недопонимаю каких-то оооочень тонких моментов :-)

dub
Не плохо, попробую.
Нужно только придумать, как с параметрами быть, но в целом мне понравилось.
Спасибо!

есть такая возможность

хе-хе, возможность-то есть, да немного не такая. :)
Так она ругнётся, что, мол, нету таких членов в классе А. А чтобы не ругнулась, надо:

Причём, если fun1/fun2 не сами по себе, а находятся в какой-нть структуре S, то всё ещё извратнее:

Если структура S — это сам object, то, соответственно, выражение: (object->*(object->fun1)) ();
(скобки вокруг object->fun1 для наглядности, а так, в принципе, необязательны).


А VC7 это не компилит и говорит следующее:

Sbtrn. Devil
Ты меня немного опередил :-)
Но ты верно заметил ошибку.

Вообщем в последней редакции получается так:

Спасибо Cool Ace за метод и Sbtrn. Devil за подсказку!

Можно с помощью функторов, можно просто с помощью системы сообщений.
Тоесть делаешь базовый класс CMessageTarget, например, и у него метод SendMessage()
с типом сообщения и параметрами и метод OnMessage() — виртуальный.
Тогда можно любому элементу управления ГУИ послать любое сообщение.
Можно сделать какой-нибудь MessageDispatcher, который будет помещать сообщения в очередь,
а потом обрабатывать ее и отсылать все хранящиеся сообщения своим адресатам.
Короче, что-то наподобие Windows message system.

Можно в качестве параметра к сообщению посылать тот же функтор — тогда система еще более гибкой получается.
Одним словом, вариантов тьма, выбирай какой по душе.

да да, ошибся я :(( просто такие возможности использую редко

Выполнения обработчика событий в CPP?

Работая над проектом, CPP, где мне нужно что-то вроде обработчика событий во время выполнения. Моя главная цель состоит в том, чтобы отслеживать различные события, что происходит в примере программы и на основе событий, конкретные обработчики запускаемых.

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

Мой вопрос это prossible создать soemthing как пользовательские eventhandlers в CPP? Если да, то есть ли какой-либо учебник для создания такого пользовательского EventHandler?

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

Я ищу событий, как не удалось войти во время цикла. успешно введен в то время как цикл, созданный объект, удаленный объект, изменил глобальную переменную и т.д.

++ сам язык C не отслеживает такие вещи, как «событие». Вообще говоря, это не обеспечивает крючки в любой из различных основных видов деятельности, которые происходят по всему коду.


Таким образом, чтобы делать то, что вы просите, требует создания инфраструктуры себя и работать его в свой код различными способами. (Или найти кого-то, кто сделал такой же работы, уже и сделал его доступным. Хотя вы все равно придется интегрировать его в свой код.)

Чтобы дать некоторое представление о том, что, возможно, придется сделать:

Для создания и удаления объектов можно переопределить new и delete оператор. Но это не распространяется на стек / местные / и т.д. объектов. В противном случае вы могли бы заклинить что — то конструкторы и деструкторы каждого класса , который вы хотите отслеживать, или даже все они происходят от общего базового класса , который инкапсулирует трекинг.

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

Для ввода петель . Вы не повезло, потому что цикл не является объектом, который может быть продлен или зацепиться. Вы буквально должны поставить какой-то вызов на каждом цикле вы хотите отслеживать.

Что касается остальной части инфраструктуры, вы, вероятно, в конечном итоге делает что-то подобное, имеющие все эти различные «события» призыв к каким-то глобальным объектом регистрации. Если вам нужны разные вещи поймать различные события над курсом программы, то вы, возможно, также необходимо создать способ регистрации и отмене регистрации слушателей (слушатели сами, основываясь на интерфейсе, чтобы получить от или станд :: функция или что-то подходит для вашей пользы дела).

Илон Маск рекомендует:  mysql_escape_string - Экранирует SQL спец-символы для mysql_query.

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

Обработка исключительных ситуаций

Исключение — это событие при выполнении программы, которое приводит к её ненормальному или неправильному поведению.
Существует два вида исключений:

  • Аппаратные (структурные, SE-Structured Exception), которые генерируются процессором. К ним относятся, например,
    • деление на 0;
    • выход за границы массива;
    • обращение к невыделенной памяти;
    • переполнение разрядной сетки.
  • Программные , генерируемые операционной системой и прикладными программами – возникают тогда, когда программа их явно инициирует. Когда встречается аномальная ситуация, та часть программы, которая ее обнаружила, может сгенерировать, или возбудить , исключение.


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

Обработка программных исключений

Фундаментальная идея обработки исключительных ситуаций состоит в том, что функция, обнаружившая проблему, но не знающая как её решить, генерирует исключение в надежде, что вызвавшая её (непосредственно или косвенно) функция сможет решить возникшую проблему. Функция, которая может решать проблемы данного типа, указывает, что она перехватывает такие исключения.

Для реализации обработки исключений в C++ используйте выражения try , throw и catch .
Блок try <…>позволяет включить один или несколько операторов, которые могут создавать исключение.
Выражение throw используется только в программных исключениях и означает, что исключительное условие произошло в блоке try . В качестве операнда выражения throw можно использовать объект любого типа. Обычно этот объект используется для передачи информации об ошибке.
Для обработки исключений, которые могут быть созданы, необходимо реализовать один или несколько блоков catch сразу после блока try . Каждый блок catch указывает тип исключения, которое он может обрабатывать.
Сразу за блоком try находится защищенный раздел кода . Выражение throw вызывает исключение, т.е. создает его.
Блок кода после catch является обработчиком исключения . Он перехватывает исключение, вызываемое, если типы в выражениях throw и catch совместимы. Если оператор catch задает многоточие (…) вместо типа, блок catch обрабатывает все типы исключений.
Поскольку блоки catch обрабатываются в порядке программы для поиска подходящего типа, обработчик с многоточием должен быть последним обработчиком для соответствующего блока try . Как правило, блок catch (…) используется для ведения журнала ошибок и выполнения специальной очистки перед остановкой выполнения программы.

Ниже приведен пример обработки программного исключения. В реальных программах посылка исключения командой throw , как правило, является следствием проверки какого-либо условия.

Вынести метод шаблонного класса в .cpp

Как вынести метод шаблонного класса из хэдера в cpp ?

3 ответа 3

Необходимо помнить, что шаблон порождает код класса только тогда, когда вы употребляете этот шаблон в программе с конкретными параметрами. Это означает, что нельзя скомпилировать модуль содержащий просто шаблон класса. Шаблон — это еще не тип (в C#, напротив, угловые скобки говорят о типе Generic ). Таким образом, реализация метода должна быть в том модуле, где этот метод используется, иначе получите Unresolved symbol. Вот пример, который скомпилировался в MSVS 2008:

foo.h:

main.cpp

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

А вообще, если у Вас возникла такая задача, стоит задуматься, на верном ли Вы пути, так сказать :)


Accountant cpp реализация обработки событий на c

Как известно, компилятор C++ обрабатывает исключительно файлы *.cpp, другими словами, что в них будет написано, то и попадет в конечную программу. Директива препроцессора #include позволяет включить в исходный файл текст из любого другого файла (как правило, это файлы *.h). Поэтому, совершенно не важно, где будет определен тот или иной метод класса (в h, или в cpp).

Мастер Windows Forms (видимо, Вы именно об этом говорите) в проектах C++/CLI автоматически совмещает объявление и определение метода в заголовочном файле. Если Вас это сильно «смущает», можете оставить в h объявление, а определение вынести в cpp.

Главное, что нужно понять, мастер просто пишет код за Вас, а Вы вправе соглашаться, или не соглашаться с ним.

Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

  • Предложено в качестве ответа Yatajga Editor 29 октября 2014 г. 7:11
  • Помечено в качестве ответа Magals 29 октября 2014 г. 7:54

Все ответы

Как известно, компилятор C++ обрабатывает исключительно файлы *.cpp, другими словами, что в них будет написано, то и попадет в конечную программу. Директива препроцессора #include позволяет включить в исходный файл текст из любого другого файла (как правило, это файлы *.h). Поэтому, совершенно не важно, где будет определен тот или иной метод класса (в h, или в cpp).

Мастер Windows Forms (видимо, Вы именно об этом говорите) в проектах C++/CLI автоматически совмещает объявление и определение метода в заголовочном файле. Если Вас это сильно «смущает», можете оставить в h объявление, а определение вынести в cpp.

Главное, что нужно понять, мастер просто пишет код за Вас, а Вы вправе соглашаться, или не соглашаться с ним.

Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!


  • Предложено в качестве ответа Yatajga Editor 29 октября 2014 г. 7:11
  • Помечено в качестве ответа Magals 29 октября 2014 г. 7:54

Как известно, компилятор C++ обрабатывает исключительно файлы *.cpp, другими словами, что в них будет написано, то и попадет в конечную программу. Директива препроцессора #include позволяет включить в исходный файл текст из любого другого файла (как правило, это файлы *.h). Поэтому, совершенно не важно, где будет определен тот или иной метод класса (в h, или в cpp).

Илон Маск рекомендует:  Четвертый borland с и его окружение

Мастер Windows Forms (видимо, Вы именно об этом говорите) в проектах C++/CLI автоматически совмещает объявление и определение метода в заголовочном файле. Если Вас это сильно «смущает», можете оставить в h объявление, а определение вынести в cpp.

Главное, что нужно понять, мастер просто пишет код за Вас, а Вы вправе соглашаться, или не соглашаться с ним.

Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

а есть возможность подкорректировать работу мастера под себя? доп. чтоб создавал событие в спп файле

Если сообщение помогло Вам, пожалуйста, не забудьте отметить его как ответ данной темы. Удачи в программировании!

Magals, мой вам совет, не используйте C++ CLI. Это язык для управляемой среды .NET. Если вы хотите перейти на эту платформу, то осваивайте язык C#. Си Шарп гораздо более простой и лёгкий в освоении язык, чем C++. Он оптимально подходит для создания настольных, мобильных и веб-приложений.

Если вы хотите осваивать системное программирование, тогда используйте обычный язык C++ (не CLI). Для этого в Visual Studio есть свои шаблоны приложений. Но в VS нет современных средств для создания приложений с GUI, таких как VCL в Borland’е. Поэтому для графических приложений либо придётся мучиться с WinAPI или MFC, либо использовать что-то стороннее, например, QT.

Язык C++ CLI по сути предназначен для одной цели — соединение управляемого (для .NET) и неуправляемого, нативного кода. То есть использовать его нужно лишь когда имеется много того и другого кода и хочется его объединить.


Magals, мой вам совет, не используйте C++ CLI. Это язык для управляемой среды .NET. Если вы хотите перейти на эту платформу, то осваивайте язык C#. Си Шарп гораздо более простой и лёгкий в освоении язык, чем C++. Он оптимально подходит для создания настольных, мобильных и веб-приложений.

Если вы хотите осваивать системное программирование, тогда используйте обычный язык C++ (не CLI). Для этого в Visual Studio есть свои шаблоны приложений. Но в VS нет современных средств для создания приложений с GUI, таких как VCL в Borland’е. Поэтому для графических приложений либо придётся мучиться с WinAPI или MFC, либо использовать что-то стороннее, например, QT.

Язык C++ CLI по сути предназначен для одной цели — соединение управляемого (для .NET) и неуправляемого, нативного кода. То есть использовать его нужно лишь когда имеется много того и другого кода и хочется его объединить.

Благодарю что отписались, возможно немного поможете мне разобраться.

Сам C# я знаю, но от начальства пришло задание написать след проект на С++ и под Visual Studio.

Я так понял все, что предлагает мне Visual C++ это: С++\CLI(CLR), MFC, Win32 и ATL -ещё не исследовал что это

MFC и Win32- я так понял это проекты которые будут написаны на чистом с++ без размешивания его с .Net и при этом не имеют явного конструктора формы/компонентов. что очень сильно усугубляет дело

С++\CLI \CLR-конструктор есть(то есть наляпать форму из кнопок можно запросто). и вроде особого проблем кодировании нет.

В общем суть задания такова. Есть такое устройство Sub20. Мы его используем для передачи данных по SPI через USB. Скорость передачи данных(работы программы) относительно ограниченна, то есть за определенное время надо отправить необходимое количество данных/пакетов. Поэтому руководство и выбрала С++. Хотя судя по тестам скорость передачи пакетов С Sharp от Visual c++/CLI отстает всего-то на 40 мс.

В общем, что бы вы выбрали для осуществления подобного задания из предлагаемых решений Visual C++ ?

Введение

Так уж исторически сложилось, что в языке С++ нет событий. Событием (event) является исходящий вызов (программисты на VB хорошо знакомы с ними) и в С++ их действительно нет. Иногда события путают с сообщениями (message), но это не верно. Сообщение это прямой вызов: например windows вызывает оконную процедуру для передачи собщения окну. Объект (система) вызывает функцию обькта(окна). Вызов происходит от объекта к объекту. В отличии от сообщения событие имеет другую механику. Объект инициирует событие и вызываются все объекты-обработчики. Т.е. от одного объекта к нескольким. Причем объект инициатор события может ничего не «знать» об его обработчиках, поэтому событие называют исходящим вызовом.

Раз уж в С++ события на уровне языка не поддерживаются, значит стоит организовать их на уровне библиотеки. Здесь приведена реализация такой библиотеки. В ней есть два класса signal и slot.

Итак, чтобы сделать какой нибудь класс источником события поместите в него переменную типа signal:


signal someEvent; // void – тип аргумента события

А чтобы сделать класс обработчиком поместите в него переменную типа slot, функцию обработчик и свяжите slot с обработчиком:

slot someHandler; // переходник

// функция обработчик события

void connect (EventRaiser& er) <

someHandler.init(er.someEvent, onEvent, this); // установим связь события с обработчиком

Так как эти объекты являются частью своих хозяев, не нужно заботится о времени жизни связи. Ее разрыв произойдет во время разрушения одного из них. Событие же инициируется вызвовом метода signal::raise:

signal someEvent; // void – тип аргумента события

someEvent.raise(); // инициация события

События

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

События являются членами класса и объявляются с помощью ключевого слова event. Чаще всего для этой цели используется следующая форма:

где делегат_события обозначает имя делегата, используемого для поддержки события, а имя_события — конкретный объект объявляемого события.


События основаны на делегатах и предоставляют им механизм публикации/подписки. В каркасе .NET события присутствуют повсюду. В приложениях Windows класс Button поддерживает событие Click. Этот тип события является делегатом. Метод-обработчик, вызываемый с событием Click, должен быть определен с параметрами, заданными в типе делегата.

Илон Маск рекомендует:  Что такое код escapeshellcmd

Как и делегаты, события поддерживают групповую адресацию. Это дает возможность нескольким объектам реагировать на уведомление о событии.

Методы экземпляра и статические методы могут быть использованы в качестве обработчиков событий, но между ними имеется одно существенное отличие. Когда статический метод используется в качестве обработчика, уведомление о событии распространяется на весь класс. А когда в качестве обработчика используется метод экземпляра, то события адресуются конкретным экземплярам объектов. Следовательно, каждый объект определенного класса, которому требуется получить уведомление о событии, должен быть зарегистрирован отдельно. На практике большинство обработчиков событий представляет собой методы экземпляра, хотя это, конечно, зависит от конкретного приложения.

Давайте рассмотрим пример:

Как видите, в данном примере создается событие UserEvent, являющееся членом делегата UI. Обработчик данного события определяется в классе UserInfo, и добавляется с помощью синтаксиса +=.

Как реализовать приемник для обработки событий CN C++?

Я пытаюсь понять обработку событий при использовании COM. У меня есть интерфейс COM-объекта, разработанный третьей стороной, который должен запускать некоторые события. Мне нужно обработать эти события из приложения C++. До сих пор у меня есть следующий код для настройки события:

Настройка событий (Main.cpp)

Моя проблема в том, что я не знаю, как реализовать EventSink? Я видел, как люди создают простой класс, который расширяет некоторую форму реализации IDispatch, но я, похоже, не имею этой реализации, и я не могу найти достойных примеров того, как создать свою собственную реализацию. В настоящее время у меня есть два метода на моем EventSink, которые, как мне известно, вызываются:

EventSink.cpp

Я не уверен, что эти методы работают правильно.

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

Обработчик событий времени выполнения в cpp?

Работаю над проектом cpp, где мне нужно что-то вроде обработчика событий времени выполнения. Моя основная цель — отслеживать различные события, происходящие в примере программы и основанные на событиях, которые запускаются определенными обработчиками.


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

Мой вопрос, возможно ли создать что-то вроде пользовательских обработчиков событий в cpp?
Если да, есть ли учебник для создания такого пользовательского обработчика событий?

например:
Событие как будто не удалось войти в цикл. успешно введен во время цикла, созданный объект, удаленный объект, измененная глобальная переменная и т. д.

Решение

Самая простая форма обработчика событий — это зарегистрированный указатель на функцию обратного вызова:

Другие решения

Я ищу такие события, как не удалось войти в цикл while. успешно
во время цикла, создан объект, удален объект, изменен глобальный
переменная и т. д.

Сам язык C ++ не отслеживает такие вещи как «события». Вообще говоря, он не предоставляет хуков к различным фундаментальным действиям, которые происходят в коде.

Поэтому для того, чтобы выполнить то, о чем вы просите, необходимо создать инфраструктуру самостоятельно и встраивать ее в свой код различными способами. (Или найти кого-то еще, кто уже проделал такую ​​же работу и сделал ее доступной. Хотя вам все равно придется интегрировать ее в свой код.)

Чтобы дать некоторое представление о том, что может быть сделано:

Для создания и удаления объектов вы можете переопределить new а также delete операторы. Но это не касается стековых / локальных / etc объектов. В противном случае вы можете втиснуть что-нибудь конструкторы и деструкторы каждого класса, который вы хотите отслеживать, или даже получить все из них из общего базового класса, который инкапсулирует отслеживание.

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

Для ввода циклов … Вам не повезло, потому что цикл не является сущностью, которую можно расширять или подключать. Вы буквально должны делать какие-то вызовы в каждом цикле, который хотите отслеживать.

Что касается остальной части инфраструктуры, вы, вероятно, в конечном итоге сделаете что-то вроде вызова всех этих различных «событий» для какого-то глобального объекта журналирования. Если вам нужно, чтобы разные вещи перехватывали разные события в течение программы, вам также может понадобиться создать способ регистрации и отмены регистрации слушателей (сами слушатели основаны на интерфейсе, производном от std :: function или любом другом подходит для вашего случая использования).

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

Accountant cpp реализация обработки событий на c

Угу, это обычные C++-указатели на функцию-член класса, а в Borland C++ Builder есть ещё и так называемые closure — это указатели на функцию-член класса, которые ещё и адрес конкретного объекта хранят, кроме адреса функции. Как можно видеть в сообщении от компилятора, запись &SomeObjectDblClick внутри какой-нибудь функции-члена класса как раз и даёт closure.

C++BuiIder использует модификатор _closure для объявления функции обработчиков событий:

Это ключевое слово определяет указатель функции с именем name. В отличие от 4-байтового адресного указателя обычной функции (который передается в кодовые регистры CS:IP) 8-байтовый _closure передает еще и скрытый параметр (непостоянный указатель this на экземпляр текущего класса).

Введение 8-байтовых указателей делает возможным не только вызывать некоторую функцию определенного класса, но и обращаться к функции в определенном экземпляре этого класса. Эта способность была заимствована из Объектного Паскаля, а _closure оказался жизненно необходимым для реализации механизма событий в Библиотеке Визуальных Компонент.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL