Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Inversus
0 / 0 / 0
Регистрация: 28.08.2016
Сообщений: 12
#1

Передача указателя на функцию-член - C++

29.08.2016, 00:05. Просмотров 1364. Ответов 41
Метки нет (Все метки)

Всем привет !

Необходимо передать функцию-член в качестве параметра другой функции-члену. Следующий код

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Menu {
    public:
    void spin();   
};
void Menu::spin() {
  ;
}
class Encoder {
  public:
    void setSpinFunc(void(Menu::*i)());
};
void Encoder::setSpinFunc(void(Menu::*i)()) {
  ;
}
int main()
{
    Menu m();
    Encoder e();
    e.setSpinFunc(m.spin);
}
вызывает ошибку: request for member 'setSpinFunc' in 'e', which is of non-class type 'Encoder()'

Уже долго туплю над этим, похоже сам не въеду, разъясните что не так.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.08.2016, 00:05
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Передача указателя на функцию-член (C++):

Передача типа указателя на функцию - C++
Всем привет. Недавно в теме начинающих возник вопрос, а можно ли передать тип (указатель на функцию) без использования typedef: ...

Шаблон RAII замены указателя на функцию - C++
шаблон raii замены указателя на фукнцию допустим имеется набор указателей на функции разных типов и существует потребность временно,...

Вызов через указатель на функцию-член - C++
Всем экспертам привет :) Разбавим раздел, так сказать. Задался тут таким вопросом: Есть класс, в котором объявлено поле типа...

Ошибка Access violation при передаче указателя в функцию - C++
выделяю память для нужд програмных и соханяю его. char *resadres =(char*) VirtualAlloc (0, 50000, MEM_COMMIT | MEM_RESERVE,...

Передача ссылки в функцию в DLL - C++
Здравствуйте. По этому мануалу сделал DLL https://msdn.microsoft.com/ru-ru/library/ms235636.aspx Возникла проблема с передачей...

Передача и возврат указателя из массива - C++ Builder
Доброго времени суток. проблема с указателями как я догадываюсь. функция im исправно работает исправно но при объединение с...

41
Avazart
Эксперт С++
7237 / 5433 / 304
Регистрация: 10.12.2010
Сообщений: 24,151
Записей в блоге: 17
31.08.2016, 19:18 #31
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Толку в этом ускорение разработки GUI.
Скорее замедление, кодом быстрее и гибче. В общем для мартышек.

Честно говоря я вообще не могу придумать случая когда такое может понадобится.
Для БД может, а в GUI что бы связывать эдит с лейблом ... глупость ... дублирующей информации как бы не должно быть.
0
Fulcrum_013
Заблокирован
31.08.2016, 19:32 #32
Цитата Сообщение от Avazart Посмотреть сообщение
что бы связывать эдит с лейблом ... глупость ... дублирующей информации как бы не должно быть.
Любая информация где то вводится и где то выводится. Единственное что пока там не уяснил есть ли такая же связь с кастомными данными. Это бы вообще конкретно жиснь облегчило бы.
К примеру в любом модальном диалоге-редакторе есть примерно такой код по занесению в него и извлечению из него данных (если контролы диалога не БД-контролы что далеко не всегда надо).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void TForm3::Edit(TUnit* aUnit){
     Unit=aUnit;
     Name->Text=Unit->Name;
     VerMajor->ItemIndex=Unit->Version.Major-1;
     VerMajor->ItemIndex=Unit->Version.Minor;
     ShowModal();
 
};
//---------------------------------------------------------------------------
void __fastcall TForm3::OkClick(TObject *Sender)
{
     Unit->Name=Name->Text;
     Unit->Version.Major=VerMajor->ItemIndex+1;
     Unit->Version.Minor=VerMajor->ItemIndex;
}
Если бы была привязка контролов к полям структуры было бы вообще здорово, особенно если бы не требовало порождения редактируемой структуры/класса от TObject.
Цитата Сообщение от Avazart Посмотреть сообщение
Скорее замедление, кодом быстрее и гибче
Там где гибкости этой штуке не хватит там код никто не отменял. А там где хватит восприниматься будет гораздо лучше, а значит и правится с меньшим количеством багов а соответсвенно и меньшим количеством отладки. Причем тем больше состояний тем в квадрате. Схемы всегда воспринимаются лучше кода.
0
Avazart
Эксперт С++
7237 / 5433 / 304
Регистрация: 10.12.2010
Сообщений: 24,151
Записей в блоге: 17
31.08.2016, 19:45 #33
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Любая информация где то вводится и где то выводится.
В том то и дело что в примерах связывание между контролами.
Что бы связывать с данными там - за мутно и не очевидно...
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Схемы всегда воспринимаются лучше кода.
А вот и нет... Код для программиста очевиден, а вот схемы которые понавыдумывали.
1
Fulcrum_013
Заблокирован
01.09.2016, 07:21 #34
Цитата Сообщение от Avazart Посмотреть сообщение
Код для программиста очевиден, а вот схемы которые понавыдумывали.
Программист тем и отличается от кодера что способен не только код накодить но и построить общую схему реализации задачи. А если разработка ведется не одним человеком а несколькими то схему чертить придется как не крути, годного для таких целей телепатора наука и техника еще не изобрела. При этом схема особенно при наличии комментов сама является докой в отличии от кода. Посему программер это сначала спец по схемам а потом уже кодер.
Да кстати интересный такой момент. При проектировани бортового софта "Энергии" и "Бурана" и пускового стола с ЦУП к ним количество потребных высоко квалифицированных программеров-кодеров было оценено в 8-10 тысяч. Для совдепии это было непозволительной роскошью. Посему соорудили язык программирования схемами ДРАКОН. Даже при том что это не ООП язык справились с задачей быстрее чем механики ракету запилили менее чем 2 тысячами программеров.

Добавлено через 3 часа 53 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
Что бы связывать с данными там - за мутно и не очевидно...
Да ладно там. 15 минут разобраться и долой кучу говнокода(имеется в виду такого кода которого в любой задаче как говна). Кстати все новое хорошо забытое старое. Примерно подобный способ связи данных с контролами для обмена данных с диалоговым окном пользовался в Turbo Vision. Только там вот так вот что куда хочешь биндить нельзя было, типы и порядок полей структуры должны были совпадать с типом данных и TabOrder контролов в окне.

Добавлено через 4 часа 44 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
А вот и нет... Код для программиста очевиден, а вот схемы которые понавыдумывали.
Код по большому счету это средство ввода программы времен телетайпов. Полных повсеместно пользуемых замен ему пока что нет. Но местами есть очень даже хорошие и вполне жизнеспособные попытки (к примеру ДРАКОН или BluePrint) которые при должном развитии в ближайшем будущем код вообще вытеснят не потеряв при этом его возможностей и гибкости а добавив простоту восприятия и скорость ввода.
0
Inversus
0 / 0 / 0
Регистрация: 28.08.2016
Сообщений: 12
01.09.2016, 17:11  [ТС] #35
В программе есть таблица векторов прерываний. В ней указатели на функции. Переделать её в массив указателей на методы Я так понял не получится потому что нет универсального указателя на класс (типа void для функций) ?

Никогда бы не подумал что придётся в такие дебри лезть.

Вообще связался с ООП в контроллере и теперь фигею - такие грабли вылазят. Нужно было все по старинке - функциями фигачить. Ощущение с родни тому как когда Я в юности понял что бейсика и паскаля не хватает для моих затей - только наоборот )
0
Avazart
Эксперт С++
7237 / 5433 / 304
Регистрация: 10.12.2010
Сообщений: 24,151
Записей в блоге: 17
01.09.2016, 18:08 #36
Цитата Сообщение от Inversus Посмотреть сообщение
понял не получится потому что нет универсального указателя на класс (типа void для функций) ?
Два void* ?
Один для объекта другое для смещения(метода)
0
Inversus
0 / 0 / 0
Регистрация: 28.08.2016
Сообщений: 12
01.09.2016, 18:45  [ТС] #37
Я опять запутался.
Цитата Сообщение от Avazart Посмотреть сообщение
Два void* ?
Один для объекта другое для смещения(метода)
Ну это понятно. Но разве указатели типа void(Object0::*ptr0)() void(Object1::*ptr1)() ... void(Object10::*ptr10)() будут однотипными с точки зрения компилятора для помещения их в массив ?

Добавлено через 5 минут
Хотя логично предположить что они одинаковой длины.
Но как тогда объявлять массив ?
0
Avazart
Эксперт С++
7237 / 5433 / 304
Регистрация: 10.12.2010
Сообщений: 24,151
Записей в блоге: 17
01.09.2016, 19:20 #38
А вот это смотрели: Простейший делегат на C++ ?
0
Fulcrum_013
Заблокирован
02.09.2016, 00:55 #39
Цитата Сообщение от Inversus Посмотреть сообщение
Я так понял не получится потому что нет универсального указателя на класс (типа void для функций) ?
Потому что указатель на метод объекта это реально два указателя - на код метода и на данные объекта. В таблице векторов прерываний место только под один. Можно занести в таблицу векторов прерываний адрес функции (это может быть и статический метод-посредник) которая вызовет нужный метод нужного объекта при этом сам указатель на объект установленный обработчиком хранить где то отдельно (не в таблице векторов прерываний, к примеру в статическом поле того же класса)

Добавлено через 17 минут
Цитата Сообщение от Inversus Посмотреть сообщение
Вообще связался с ООП в контроллере и теперь фигею - такие грабли вылазят. Нужно было все по старинке - функциями фигачить. Ощущение с родни тому как когда Я в юности понял что бейсика и паскаля не хватает для моих затей - только наоборот )
Вообще похоже пока что вопрос немного по другому строить надо - зачем вообще связались с контроллером (а с ООП в контроллере тем более). Вообще для того чтобы с контроллером работать а тем более с ООП нужно знать подкапотные дела устройства объектов и то что можно в векторах прерываний и т.п. разместить (фактически подкапотные дела контроллера). Стоит чуток глубже капнуть эту тему и все станет элементарно без всяких граблей. Сталкивался с обработкой прерываний под ДОС вкупе с ООП (на любом контроллере это будет аналогично ). Никаких граблей там при знании подкапотного устройства объекта нет. Так что стоит покапать немного в сторону как объект функциклит. На самом деле при вызове метода объекта ему передается один скрытый дополнительный параметр - именно этот указатель на данные на которые место в таблице прерываний не отведено. Т.е. стоит просто реализовать отдельное хранение этого указателя и вызов метода из обработчика прерывания и все ок, разве что кроме небольшого накладного расхода на еще один Indirect Call.
0
Inversus
0 / 0 / 0
Регистрация: 28.08.2016
Сообщений: 12
02.09.2016, 23:29  [ТС] #40
Цитата Сообщение от Avazart Посмотреть сообщение
А вот это смотрели: Простейший делегат на C++ ?
Да видел эту каркалыгу. Мне вот интересно, люди на хабре вообще проверяют то что им преподносят, или просто с умным видом поддакивают - мол, да да, мы умные, мы во всем разобрались. Пример даже не компилируется - два предупреждения и две ошибки.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Потому что указатель на метод объекта это реально два указателя
Это Я уже понял. Я имел ввиду универсальный указатель на любой класс - ClassA, ClassB, ClassC и т.д. т.е. что типа того самого пресловутого делегата.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
зачем вообще связались с контроллером
- В смысле ?) нужен был контроллер, поэтому и связался. А что, есть какие-то еще варианты ?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Сталкивался с обработкой прерываний под ДОС
Тот самый DOS 6.22 ? Но во первых процессор и контроллер это немного разные вещи все-же и специфика у них различная. На интеловском ассемблере Я тоже писал. В процессоре как правило не стоит задачи отлавливать каждый бит шины, в отличии от контроллера. Тем не менее стандартными средствами AVR можно отловить только внешние прерывание целого порта (коих в моем случае всего 3), а дальше - сам изголяйся. Т.е. приходится обрабатывать свою таблицу векторов внешних прерываний. И то что у Вас прокатило с процессором на языке, фактически под него заточенном, не прокатит с AVR - много нюансов, на которые Я и натыкаюсь теперь.

Во вторых Я не стал с нуля писать обработку прерываний, а взял за основу известный код, (но не ООП однако) - можете ознакомиться если интересно http://playground.arduino.cc/Main/PcInt, заодно и про подкапотное пространство с авторами предметно подискутировать можете )

В целом, программа работает и в нынешнем виде, но с костылями. Просто хотелось элегантности и универсальности.

Добавлено через 20 минут
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Т.е. стоит просто реализовать отдельное хранение этого указателя и вызов метода из обработчика прерывания и все ок, разве что кроме небольшого накладного расхода на еще один Indirect Call.
Ну да как Я теперь понял, через делагаты, не так просто как думалось.
0
Avazart
Эксперт С++
7237 / 5433 / 304
Регистрация: 10.12.2010
Сообщений: 24,151
Записей в блоге: 17
03.09.2016, 00:29 #41
Кроме двух указателей нужно еще и как то хранить типы.
Цитата Сообщение от Inversus Посмотреть сообщение
Да видел эту каркалыгу. Мне вот интересно, люди на хабре вообще проверяют то что им преподносят, или просто с умным видом поддакивают - мол, да да, мы умные, мы во всем разобрались. Пример даже не компилируется - два предупреждения и две ошибки.
Лично у меня компилится и работает (MSVC2010 и RAD XE3).

http://ideone.com/cVHRAL
0
Fulcrum_013
Заблокирован
03.09.2016, 00:40 #42
Цитата Сообщение от Inversus Посмотреть сообщение
В процессоре как правило не стоит задачи отлавливать каждый бит шины, в отличии от контроллера.
Именно такая задача и стояла. Кроме работы с ком-портами садились на шину УВМ совсем другой архитектуры через самодельный адаптер.
Цитата Сообщение от Inversus Посмотреть сообщение
Тем не менее стандартными средствами AVR можно отловить только внешние прерывание целого порта (коих в моем случае всего 3), а дальше - сам изголяйся
. То же самое и у КР580 и у интела причем у интела прерываний 16 а портов целая простыня (т.е. на одном прерывании висит куча портов потом еще разбирайся опрашивая регистры внешних устройств кто сказал царя не надо ). И у всего что видел тоже так.

Цитата Сообщение от Inversus Посмотреть сообщение
Во вторых Я не стал с нуля писать обработку прерываний, а взял за основу известный код, (но не ООП однако)
Ну это похоже первая ошибка и главная в работе с прерываниями. Обработчику прерывания обычно нужна не абсолютная универсальность а универсальность в рамках задачи или даже подзадачи. Т.е. обработчик или наборы обработчиков лучше делать самостоятельно. Но для этого нужно чуток по глубже разобраться как прерывания функциклят. Т.е. научится мыслить прерывааниями. Это кстати очень на мультипоток похоже только с приоритетами.
Цитата Сообщение от Inversus Посмотреть сообщение
В целом, программа работает и в нынешнем виде, но с костылями. Просто хотелось элегантности и универсальности.
Ну если дело касается прерываний то обработчик прерывания вызывающий делегата это не костыль а неизбежность. Если нужно скажем по своему делегату на каждый пин сделать можно обработчику прерываний дать массив делегатов и будет для каждого пина своего делегата вызывать. Это в принципе одно и тоже что дать ему массив интов которые передавать дальше в какую то функцию выбирая нужный при срабатывании каждого определенного бита.
0
03.09.2016, 00:40
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.09.2016, 00:40
Привет! Вот еще темы с ответами:

Передача указателя на объект класса через this - C++ Builder
Всем участникам форума горячий ПРИВЕТ! Вопрос такой. cl.h class cl { public: void cl(); int a; private: DWORD...

Передача указателя на функцию-член класса - C++
Необходимо передать фунцию-член класса как аргумент в функцию другого класса. Код: Файл main.cpp #include "head.hpp" int...

Передача указателя на шаблонную функцию в другую функцию - C++
Пишу тест для нескольких улучшений квиксорта с измерением времени. Функция benchmark принимает итераторы для диапазона элементов, указатель...

Передача указателя в функцию - C++
Здравствуйте. Прошу помощи, сижу уже пару часов читаю мануалы, но так и не смог до конца понять, что мне делать. Есть вот такой код: ...


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

Или воспользуйтесь поиском по форуму:
42
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.