0 / 0 / 0
Регистрация: 28.08.2016
Сообщений: 16
1

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

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

Author24 — интернет-сервис помощи студентам
Всем привет !

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

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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.08.2016, 00:05
Ответы с готовыми решениями:

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

Передача указателя на CALLBACK функцию
делаю класс приложения для более быстрого создания программ и просто инкапсуляции всего и вся)) и...

Передача указателя на функцию-член класса
Необходимо передать фунцию-член класса как аргумент в функцию другого класса. Код: Файл...

Хранение в map указателя на функцию-член шаблонного класса
Здравствуйте! Сделал я себе вызов написать джунгли из ООП деревьев, типо, объекты обмениваются...

41
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
30.08.2016, 02:49 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Avazart Посмотреть сообщение
К примеру что мешает сделать так:
Ну не мешает то в принципе ничего. Только требует чтобы класс Encoder знал спецификацию класса AbstractMenu. Делегат же этого не требует а делает то же самое, что и избавляет от кучи головняка при проектировниии иерархии.

Добавлено через 16 минут
Цитата Сообщение от Avazart Посмотреть сообщение
Компоненты видны "снаружи" модуля, так как находятся в секции __published
Не смертельно. В некоторых ООП языках вообще в начале их существования закрытых секций не было. Хотя действительно стоило бы разделить модификатор видимости и модификатор "доступен для визуального редактировния". Они по сути описывают независимые друг от друга переключатели. Хотя это и потянет за собой некоторые неоднозначности в плане а что именно сереализировать/десериализировать и опять же в доступе внешнего сериализатора/десериализатора к компонентам в защищенных областях. Хотя в принципе и это разруливается.

Добавлено через 58 минут
Цитата Сообщение от Avazart Посмотреть сообщение
К примеру что мешает сделать так:
Да кстати при всем при этом нативный (поддерживаемый компилятором) делегат будет работать быстрее. Т.к. для нативного делегата VMT-lookup осуществляется в момент инициализации, а для любого из возможных костылей на эту тему в момент вызова.

Добавлено через 18 минут
Цитата Сообщение от Avazart Посмотреть сообщение
MSVC продвигает давно C# у которого "включено"
Визуальное там только формошлепство да и то до Билдеровского в этом плане не дотягивает. А в том что касается не формошлепства мусоросборник мешает. Просто предпочитаю объекты делать фунциклящие по принципу по принципу "создал настроил добавил в иерархию и забыл". Когда как и что ему делать включая удаление объект знает сам.

Добавлено через 6 минут
А шарп это на самом деле улучшенная Java, адаптированная к КОП и визуальному формошлепству а не улучшенный C++ (назван так потому как Sun был категорически против внесения изменений и расширений в спецификацию Java)).

Добавлено через 1 час 37 минут
Цитата Сообщение от Avazart Посмотреть сообщение
MSVC продвигает давно C# у которого "включено".
Кстати так же включено в Visual C++.NET , есть в С++ Builder, есть в Qt в общем везде есть механизмы на тему делегатов свойств и RTTI кроме стандарта. А есть потому как нужны для реализации компонентно-ориентированной парадигмы.
0
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
30.08.2016, 09:12 22
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Визуальное там только формошлепство
А что должно быть?
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
и то до Билдеровского в этом плане не дотягивает
Что имеется ввиду?
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Просто предпочитаю объекты делать фунциклящие по принципу по принципу "создал настроил добавил в иерархию и забыл". Когда как и что ему делать включая удаление объект знает сам.
А в C# (.NET) и Qt Вы хотите сказать не так?
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
30.08.2016, 10:11 23
Цитата Сообщение от pav1uxa Посмотреть сообщение
А что должно быть?
Ну хотя бы какая то работа с ливером (Инет/БД/сокеты/сенсоры/акции/перехват сообщений ОС) с возможностью расширения набора. Это как минимум для того чтобы эта штука вообще могла называться средством визуальной разработки.
Цитата Сообщение от pav1uxa Посмотреть сообщение
Что имеется ввиду?
Ну как минимум набор компонентов.
Цитата Сообщение от pav1uxa Посмотреть сообщение
А в C# (.NET) и Qt Вы хотите сказать не так?
В Qt это тоже возможно, это ведь все таки С++. А в шарпе мусоросборник мешает, потому как мусоросборник некоторые проблемы лечит отрубая голову. К примеру недопущение висячих ссылок путем неудаления объекта на который они есть. Принудительное удаление /самоудаление объекта на который имеются ссылки с вычисткой ссылок из всех содержащих их списков в шарпе будет реализовать куда как потруднее чем в С++, а тем более будет совсем не на пользу скорости работы сборщика мусора которому и так в разветвленном дереве с паритетными связями живется несладко (если большинство этих ссылок еще и двунаправленными будут ему совсем поплохеет). А бывают такие задачки когда объект должен не просто ссылки считать но и типы тех кто на него ссылается, и при нарушении минимально допустимого комплекта ссылок удаляться, оповещая ссылающихся, некоторые из которых сего тоже могут не пережить. От мусоросборщика при этом толку ноль а геммороя из за отсутствия деструкторов куда больше. А в С++ (в том числе в Qt) это всего лишь оверхед по памяти на указатели до 3,5 раз и не более.
0
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
30.08.2016, 10:30 24
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну хотя бы какая то работа с ливером (Инет/БД/сокеты/сенсоры/акции/перехват сообщений ОС) с возможностью расширения набора. Это как минимум для того чтобы эта штука вообще могла называться средством визуальной разработки.
Конкретизируйте.
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну как минимум набор компонентов.
Конкретизируйте.
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
а геммороя из за отсутствия деструкторов куда больше
Есть Dispose()
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
30.08.2016, 11:13 25
Цитата Сообщение от pav1uxa Посмотреть сообщение
Конкретизируйте.
Ну если конкретно то в комплекте с билдером вкладок (разделов) компонент больше чем список компонент с шарпом. Из них процентов 90 не визуальные, а обеспечивающие работу с БД, сокетами, протоколами интернета (как клиентские так и серверные), облаком, REST-серверами, датчиками, сообщениями ОС и т.д. и т.п, Которые тоже визуально настраиваются и связываются между собой.

Добавлено через 16 минут
Цитата Сообщение от pav1uxa Посмотреть сообщение
Есть Dispose()
Ну то понятно что делается метод и вместо удаления именно он и вызывается, делая то же что и деструктор. Но при этом объект накапливает ссылки на всех кто на него ссылается. т.е. получается хранит динамический массив или связный список обратных ссылок (круговых), что достаточно сильно будет затормаживать сборщик памяти на разветвленной структуре, при этом чем больше паритетных связей (связи не узел-дочерний узел) тем труднее будет разгрести все это сборщику мусора, при том что он тратит время на обход всей этой структуры по всем циклам графа связей при каждой уборке а не один раз при удалении, да и то от эпицентра удаления до ближайших выживших.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
31.08.2016, 17:52 26
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну если конкретно то в комплекте с билдером вкладок (разделов) компонент больше чем список компонент с шарпом. Из них процентов 90 не визуальные, а обеспечивающие работу с БД, сокетами, протоколами интернета (как клиентские так и серверные), облаком, REST-серверами, датчиками, сообщениями ОС и т.д. и т.п, Которые тоже визуально настраиваются и связываются между собой.
То же мне визуальная разработка.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2016, 18:31 27
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
То же мне визуальная разработка.
Ну из нового добавили такое средство LiveBindings

Видео




Но я как бы не просек фишку пока. Какой от нее прок...
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
31.08.2016, 18:57 28
Цитата Сообщение от Avazart Посмотреть сообщение
Какой от нее прок...
Дата биндинг. Большинство переключений состояний и занесения данных из контрола в контрол теперь можно не кодом делать а схемой.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2016, 19:00 29
Да только толку с этого ноль...
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
31.08.2016, 19:06 30
Цитата Сообщение от Avazart Посмотреть сообщение
Да только толку с этого ноль...
Толку в этом ускорение разработки GUI. Там где GUI огромные и имеют множество настроек будет очень даже заметно.
Они все таки в этом плане на крупные и сверхкрупные корпоративные хеллоуверды ориентированы а не на просто хеллоуверды.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2016, 19:18 31
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Толку в этом ускорение разработки GUI.
Скорее замедление, кодом быстрее и гибче. В общем для мартышек.

Честно говоря я вообще не могу придумать случая когда такое может понадобится.
Для БД может, а в GUI что бы связывать эдит с лейблом ... глупость ... дублирующей информации как бы не должно быть.
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
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
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
31.08.2016, 19:45 33
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Любая информация где то вводится и где то выводится.
В том то и дело что в примерах связывание между контролами.
Что бы связывать с данными там - за мутно и не очевидно...
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Схемы всегда воспринимаются лучше кода.
А вот и нет... Код для программиста очевиден, а вот схемы которые понавыдумывали.
1
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
01.09.2016, 07:21 34
Цитата Сообщение от Avazart Посмотреть сообщение
Код для программиста очевиден, а вот схемы которые понавыдумывали.
Программист тем и отличается от кодера что способен не только код накодить но и построить общую схему реализации задачи. А если разработка ведется не одним человеком а несколькими то схему чертить придется как не крути, годного для таких целей телепатора наука и техника еще не изобрела. При этом схема особенно при наличии комментов сама является докой в отличии от кода. Посему программер это сначала спец по схемам а потом уже кодер.
Да кстати интересный такой момент. При проектировани бортового софта "Энергии" и "Бурана" и пускового стола с ЦУП к ним количество потребных высоко квалифицированных программеров-кодеров было оценено в 8-10 тысяч. Для совдепии это было непозволительной роскошью. Посему соорудили язык программирования схемами ДРАКОН. Даже при том что это не ООП язык справились с задачей быстрее чем механики ракету запилили менее чем 2 тысячами программеров.

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

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

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

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

Добавлено через 5 минут
Хотя логично предположить что они одинаковой длины.
Но как тогда объявлять массив ?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.09.2016, 19:20 38
А вот это смотрели: Простейший делегат на C++ ?
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
02.09.2016, 00:55 39
Цитата Сообщение от Inversus Посмотреть сообщение
Я так понял не получится потому что нет универсального указателя на класс (типа void для функций) ?
Потому что указатель на метод объекта это реально два указателя - на код метода и на данные объекта. В таблице векторов прерываний место только под один. Можно занести в таблицу векторов прерываний адрес функции (это может быть и статический метод-посредник) которая вызовет нужный метод нужного объекта при этом сам указатель на объект установленный обработчиком хранить где то отдельно (не в таблице векторов прерываний, к примеру в статическом поле того же класса)

Добавлено через 17 минут
Цитата Сообщение от Inversus Посмотреть сообщение
Вообще связался с ООП в контроллере и теперь фигею - такие грабли вылазят. Нужно было все по старинке - функциями фигачить. Ощущение с родни тому как когда Я в юности понял что бейсика и паскаля не хватает для моих затей - только наоборот )
Вообще похоже пока что вопрос немного по другому строить надо - зачем вообще связались с контроллером (а с ООП в контроллере тем более). Вообще для того чтобы с контроллером работать а тем более с ООП нужно знать подкапотные дела устройства объектов и то что можно в векторах прерываний и т.п. разместить (фактически подкапотные дела контроллера). Стоит чуток глубже капнуть эту тему и все станет элементарно без всяких граблей. Сталкивался с обработкой прерываний под ДОС вкупе с ООП (на любом контроллере это будет аналогично ). Никаких граблей там при знании подкапотного устройства объекта нет. Так что стоит покапать немного в сторону как объект функциклит. На самом деле при вызове метода объекта ему передается один скрытый дополнительный параметр - именно этот указатель на данные на которые место в таблице прерываний не отведено. Т.е. стоит просто реализовать отдельное хранение этого указателя и вызов метода из обработчика прерывания и все ок, разве что кроме небольшого накладного расхода на еще один Indirect Call.
0
0 / 0 / 0
Регистрация: 28.08.2016
Сообщений: 16
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
02.09.2016, 23:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.09.2016, 23:29
Помогаю со студенческими работами здесь

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

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

Передача указателя на функцию
Доброго дня Форумчане. Хотелось бы узнать как вызывать функцию получив на нее указатель? пример...

Передача в функцию указателя
Почему плохо передавать в функцию указатель на строку или массив и возвращать указатель на строку...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru