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

C++

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

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

29.08.2016, 00:05. Просмотров 1135. Ответов 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()'

Уже долго туплю над этим, похоже сам не въеду, разъясните что не так.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Fulcrum_013
657 / 725 / 72
Регистрация: 14.12.2014
Сообщений: 5,650
Завершенные тесты: 3
30.08.2016, 02:49     Передача указателя на функцию-член #21
Цитата Сообщение от 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 кроме стандарта. А есть потому как нужны для реализации компонентно-ориентированной парадигмы.
pav1uxa
1779 / 1619 / 617
Регистрация: 23.01.2014
Сообщений: 5,850
Завершенные тесты: 1
30.08.2016, 09:12     Передача указателя на функцию-член #22
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Визуальное там только формошлепство
А что должно быть?
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
и то до Билдеровского в этом плане не дотягивает
Что имеется ввиду?
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Просто предпочитаю объекты делать фунциклящие по принципу по принципу "создал настроил добавил в иерархию и забыл". Когда как и что ему делать включая удаление объект знает сам.
А в C# (.NET) и Qt Вы хотите сказать не так?
Fulcrum_013
657 / 725 / 72
Регистрация: 14.12.2014
Сообщений: 5,650
Завершенные тесты: 3
30.08.2016, 10:11     Передача указателя на функцию-член #23
Цитата Сообщение от pav1uxa Посмотреть сообщение
А что должно быть?
Ну хотя бы какая то работа с ливером (Инет/БД/сокеты/сенсоры/акции/перехват сообщений ОС) с возможностью расширения набора. Это как минимум для того чтобы эта штука вообще могла называться средством визуальной разработки.
Цитата Сообщение от pav1uxa Посмотреть сообщение
Что имеется ввиду?
Ну как минимум набор компонентов.
Цитата Сообщение от pav1uxa Посмотреть сообщение
А в C# (.NET) и Qt Вы хотите сказать не так?
В Qt это тоже возможно, это ведь все таки С++. А в шарпе мусоросборник мешает, потому как мусоросборник некоторые проблемы лечит отрубая голову. К примеру недопущение висячих ссылок путем неудаления объекта на который они есть. Принудительное удаление /самоудаление объекта на который имеются ссылки с вычисткой ссылок из всех содержащих их списков в шарпе будет реализовать куда как потруднее чем в С++, а тем более будет совсем не на пользу скорости работы сборщика мусора которому и так в разветвленном дереве с паритетными связями живется несладко (если большинство этих ссылок еще и двунаправленными будут ему совсем поплохеет). А бывают такие задачки когда объект должен не просто ссылки считать но и типы тех кто на него ссылается, и при нарушении минимально допустимого комплекта ссылок удаляться, оповещая ссылающихся, некоторые из которых сего тоже могут не пережить. От мусоросборщика при этом толку ноль а геммороя из за отсутствия деструкторов куда больше. А в С++ (в том числе в Qt) это всего лишь оверхед по памяти на указатели до 3,5 раз и не более.
pav1uxa
1779 / 1619 / 617
Регистрация: 23.01.2014
Сообщений: 5,850
Завершенные тесты: 1
30.08.2016, 10:30     Передача указателя на функцию-член #24
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну хотя бы какая то работа с ливером (Инет/БД/сокеты/сенсоры/акции/перехват сообщений ОС) с возможностью расширения набора. Это как минимум для того чтобы эта штука вообще могла называться средством визуальной разработки.
Конкретизируйте.
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну как минимум набор компонентов.
Конкретизируйте.
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
а геммороя из за отсутствия деструкторов куда больше
Есть Dispose()
Fulcrum_013
657 / 725 / 72
Регистрация: 14.12.2014
Сообщений: 5,650
Завершенные тесты: 3
30.08.2016, 11:13     Передача указателя на функцию-член #25
Цитата Сообщение от pav1uxa Посмотреть сообщение
Конкретизируйте.
Ну если конкретно то в комплекте с билдером вкладок (разделов) компонент больше чем список компонент с шарпом. Из них процентов 90 не визуальные, а обеспечивающие работу с БД, сокетами, протоколами интернета (как клиентские так и серверные), облаком, REST-серверами, датчиками, сообщениями ОС и т.д. и т.п, Которые тоже визуально настраиваются и связываются между собой.

Добавлено через 16 минут
Цитата Сообщение от pav1uxa Посмотреть сообщение
Есть Dispose()
Ну то понятно что делается метод и вместо удаления именно он и вызывается, делая то же что и деструктор. Но при этом объект накапливает ссылки на всех кто на него ссылается. т.е. получается хранит динамический массив или связный список обратных ссылок (круговых), что достаточно сильно будет затормаживать сборщик памяти на разветвленной структуре, при этом чем больше паритетных связей (связи не узел-дочерний узел) тем труднее будет разгрести все это сборщику мусора, при том что он тратит время на обход всей этой структуры по всем циклам графа связей при каждой уборке а не один раз при удалении, да и то от эпицентра удаления до ближайших выживших.
Dmitriy_M
1339 / 1220 / 111
Регистрация: 20.03.2009
Сообщений: 4,352
Записей в блоге: 11
31.08.2016, 17:52     Передача указателя на функцию-член #26
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну если конкретно то в комплекте с билдером вкладок (разделов) компонент больше чем список компонент с шарпом. Из них процентов 90 не визуальные, а обеспечивающие работу с БД, сокетами, протоколами интернета (как клиентские так и серверные), облаком, REST-серверами, датчиками, сообщениями ОС и т.д. и т.п, Которые тоже визуально настраиваются и связываются между собой.
То же мне визуальная разработка.
Avazart
7066 / 5243 / 263
Регистрация: 10.12.2010
Сообщений: 23,070
Записей в блоге: 17
31.08.2016, 18:31     Передача указателя на функцию-член #27
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
То же мне визуальная разработка.
Ну из нового добавили такое средство LiveBindings

Видео




Но я как бы не просек фишку пока. Какой от нее прок...
Fulcrum_013
657 / 725 / 72
Регистрация: 14.12.2014
Сообщений: 5,650
Завершенные тесты: 3
31.08.2016, 18:57     Передача указателя на функцию-член #28
Цитата Сообщение от Avazart Посмотреть сообщение
Какой от нее прок...
Дата биндинг. Большинство переключений состояний и занесения данных из контрола в контрол теперь можно не кодом делать а схемой.
Avazart
7066 / 5243 / 263
Регистрация: 10.12.2010
Сообщений: 23,070
Записей в блоге: 17
31.08.2016, 19:00     Передача указателя на функцию-член #29
Да только толку с этого ноль...
Fulcrum_013
657 / 725 / 72
Регистрация: 14.12.2014
Сообщений: 5,650
Завершенные тесты: 3
31.08.2016, 19:06     Передача указателя на функцию-член #30
Цитата Сообщение от Avazart Посмотреть сообщение
Да только толку с этого ноль...
Толку в этом ускорение разработки GUI. Там где GUI огромные и имеют множество настроек будет очень даже заметно.
Они все таки в этом плане на крупные и сверхкрупные корпоративные хеллоуверды ориентированы а не на просто хеллоуверды.
Avazart
7066 / 5243 / 263
Регистрация: 10.12.2010
Сообщений: 23,070
Записей в блоге: 17
31.08.2016, 19:18     Передача указателя на функцию-член #31
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Толку в этом ускорение разработки GUI.
Скорее замедление, кодом быстрее и гибче. В общем для мартышек.

Честно говоря я вообще не могу придумать случая когда такое может понадобится.
Для БД может, а в GUI что бы связывать эдит с лейблом ... глупость ... дублирующей информации как бы не должно быть.
Fulcrum_013
657 / 725 / 72
Регистрация: 14.12.2014
Сообщений: 5,650
Завершенные тесты: 3
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 Посмотреть сообщение
Скорее замедление, кодом быстрее и гибче
Там где гибкости этой штуке не хватит там код никто не отменял. А там где хватит восприниматься будет гораздо лучше, а значит и правится с меньшим количеством багов а соответсвенно и меньшим количеством отладки. Причем тем больше состояний тем в квадрате. Схемы всегда воспринимаются лучше кода.
Avazart
7066 / 5243 / 263
Регистрация: 10.12.2010
Сообщений: 23,070
Записей в блоге: 17
31.08.2016, 19:45     Передача указателя на функцию-член #33
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Любая информация где то вводится и где то выводится.
В том то и дело что в примерах связывание между контролами.
Что бы связывать с данными там - за мутно и не очевидно...
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Схемы всегда воспринимаются лучше кода.
А вот и нет... Код для программиста очевиден, а вот схемы которые понавыдумывали.
Fulcrum_013
657 / 725 / 72
Регистрация: 14.12.2014
Сообщений: 5,650
Завершенные тесты: 3
01.09.2016, 07:21     Передача указателя на функцию-член #34
Цитата Сообщение от Avazart Посмотреть сообщение
Код для программиста очевиден, а вот схемы которые понавыдумывали.
Программист тем и отличается от кодера что способен не только код накодить но и построить общую схему реализации задачи. А если разработка ведется не одним человеком а несколькими то схему чертить придется как не крути, годного для таких целей телепатора наука и техника еще не изобрела. При этом схема особенно при наличии комментов сама является докой в отличии от кода. Посему программер это сначала спец по схемам а потом уже кодер.
Да кстати интересный такой момент. При проектировани бортового софта "Энергии" и "Бурана" и пускового стола с ЦУП к ним количество потребных высоко квалифицированных программеров-кодеров было оценено в 8-10 тысяч. Для совдепии это было непозволительной роскошью. Посему соорудили язык программирования схемами ДРАКОН. Даже при том что это не ООП язык справились с задачей быстрее чем механики ракету запилили менее чем 2 тысячами программеров.

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

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

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

Вообще связался с ООП в контроллере и теперь фигею - такие грабли вылазят. Нужно было все по старинке - функциями фигачить. Ощущение с родни тому как когда Я в юности понял что бейсика и паскаля не хватает для моих затей - только наоборот )
Avazart
7066 / 5243 / 263
Регистрация: 10.12.2010
Сообщений: 23,070
Записей в блоге: 17
01.09.2016, 18:08     Передача указателя на функцию-член #36
Цитата Сообщение от Inversus Посмотреть сообщение
понял не получится потому что нет универсального указателя на класс (типа void для функций) ?
Два void* ?
Один для объекта другое для смещения(метода)
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 минут
Хотя логично предположить что они одинаковой длины.
Но как тогда объявлять массив ?
Avazart
7066 / 5243 / 263
Регистрация: 10.12.2010
Сообщений: 23,070
Записей в блоге: 17
01.09.2016, 19:20     Передача указателя на функцию-член #38
А вот это смотрели: Простейший делегат на C++ ?
Fulcrum_013
657 / 725 / 72
Регистрация: 14.12.2014
Сообщений: 5,650
Завершенные тесты: 3
02.09.2016, 00:55     Передача указателя на функцию-член #39
Цитата Сообщение от Inversus Посмотреть сообщение
Я так понял не получится потому что нет универсального указателя на класс (типа void для функций) ?
Потому что указатель на метод объекта это реально два указателя - на код метода и на данные объекта. В таблице векторов прерываний место только под один. Можно занести в таблицу векторов прерываний адрес функции (это может быть и статический метод-посредник) которая вызовет нужный метод нужного объекта при этом сам указатель на объект установленный обработчиком хранить где то отдельно (не в таблице векторов прерываний, к примеру в статическом поле того же класса)

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

Передача ссылки и указателя в функцию C++
Передача указателя в функцию по ссылке C++
C++ Передача указателя в функцию
Передача указателя на функцию C++
C++ Передача указателя на шаблонную функцию в другую функцию

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

Или воспользуйтесь поиском по форуму:
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.
Ну да как Я теперь понял, через делагаты, не так просто как думалось.
Yandex
Объявления
02.09.2016, 23:29     Передача указателя на функцию-член
Ответ Создать тему
Опции темы

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