Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Указатели на функции С++
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
nice_vladi
Всем привет.

Начал осваивать С++ и в один прекрасный момент подумал, что было бы не плохо вызывать функции по указателям на них.

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

НО! В какой-то момент я задумался о целесообразности применения, да и вообще корректности использования. Приведу пример: есть такая вещь, как goto: Но ее применять не рекомендуется,
потому-что - потому-что.

Есть ли какие-то подобные рекомендации по применению указателей на функции? Ну и вообще, подводные камни, так называемые.

Visual Studio 2013

Спасибо! biggrin.gif
gosha-z
Навскидку в голову приходит только аккуратное слежение за calling convention.
Сергей Борщ
Никаких особых противопоказаний нет. Если нужно - используйте, если не нужно - не используйте. Без фанатизма, как и любую другую языковую конструкцию. Поскольку пишете на плюсах, то обратите внимание, что указатель на функцию и указатель на функцию-член - две большие разницы и синтаксис у них тоже очень разный.
k155la3
Указатели на функции использовать можно, если в этом есть смысл или необходимость.
Например, Вы выбираете определенное действие в некой последовательности, из набора, скажем, 100 функций.
Причем эти наборы разные, и/или могут вычисляться.
Приечем Вы можете в любое время заменить любой из указателей, не изменяя основного алгоритма.
В ЭТОМ случае создаете массив указателей на функциии и вызов(а) делеаете по индексу, "переключая" или вычисляя нужный.
Это скорее метода для С.
------
А то что Вы спрашиваете, по-моему, и так обеспечивается CPP операторами точка и -->
при вызове метода (функции), своего или унаследованного.


DASM
https://pro-prof.com/forums/forum/programmi...cplusplus_notes
Чрезвычайно полезный блог. 98 % программеров на Срр толком и не знают, что они делают. О goto
Цитата
Оператор goto это гораздо более порядочный инструмент чем, например, C-style cast, или «сишная» функция exit.

Некоторые авторы все вселенские беды приписывают этому оператору. Они готовы сжечь его на костре как ведьму, если бы это было возможно.

«Ругание» goto — совершенно бессмысленная трата времени и чернил

https://pro-prof.com/forums/topic/6-cplusplus-goto

https://pro-prof.com/forums/topic/7-cplusplus_inheritance
А тут хорошее размышление о наследовании, оное при знакомстве с языком пихают где ни попадя (я в книге прочел) и имеют много проблем. Вообше С++ язык, к которому надо прийти самому, когда надоест ловить глюки на (c-ctyle) cast и подобной хрени.

"из набора, скажем, 100 функций." явно ошибка проектирования, так не бывает. Скорее всего тут подойдет шаблон интерпретатора

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

А первый 30 страниц любого "для чайников" стоит начать с UML

И многое сейчас выглядит иначе, чем 10 лет над. Например венегрская нотация - вредная вещь, а количество комментариев к коду - должно стремиться к нулю
_pv
Цитата(DASM @ Nov 11 2017, 23:16) *
"из набора, скажем, 100 функций." явно ошибка проектирования, так не бывает.

ну вот есть какое-нибудь устройство с кучей регистров.
при получении пакета с чтением/записью регистра вместо большого switch имхо проще руками сделать массив функций из которого нужная позовётся по адресу регистра.
пусть этот массив и будет забит в основном стандартной заглушкой, если там хотя бы десяток другой различных функций наберётся уже красивее выглядеть будет.
DASM
Цитата(_pv @ Nov 11 2017, 20:37) *
ну вот есть какое-нибудь устройство с кучей регистров.
при получении пакета с чтением/записью регистра вместо большого switch имхо проще руками сделать массив функций из которого нужная позовётся по адресу регистра.
пусть этот массив и будет забит в основном стандартной заглушкой, если там хотя бы десяток другой различных функций наберётся уже красивее выглядеть будет.

А свитч то зачем? Регистры все разных типов, что их надо устанавливать совершенно разным кодом?
_pv
Цитата(DASM @ Nov 12 2017, 00:04) *
А свитч то зачем? Регистры все разных типов, что их надо устанавливать совершенно разным кодом?

ну пусть это будут регистры которые отвечают за всякую разную периферию, соответственно при записи определённых регистров надо делать определённые действия, а не просто записать значение в память.
k155la3
Цитата(DASM @ Nov 11 2017, 21:16) *
. . .
"из набора, скажем, 100 функций." явно ошибка проектирования, так не бывает. Скорее всего тут подойдет шаблон интерпретатора
. . . .

Вполне возможно. Но яж выше уточнил, что "когда смысл или необходимость". Привел для примера.
Хотя сам делал с использованием указателей на ф-ии систему многоуровневого и многопунктного меню,
по той причине, чтобы все меню было видно компактно, в виде одного массива-таблицы структур.
Переход между пунктами и между меню - с использованием индексов. Проверено на практике.
С интерпретатором надо будет юлозить по стуктурированному коду.
Еще один из вариантов использования - реализация автоматов или томуподобного.
(база индекса - состояние, смещение - сигнал). Опятьже - например. То что делается стандартно на case-switch.
Но думаю "детали" ТС неинтересны sm.gif

ps - таблицы виртуальных функций.
Я и уточняю у ТС, "онож уже есть" sm.gif

Цитата(nice_vladi @ Nov 11 2017, 14:08) *
. . . Приведу пример: есть такая вещь, как goto: Но ее применять не рекомендуется,
потому-что - потому-что.
. . .

Для программ на ASM использование безусловного перехода JMP addr - аналога goto
никаких ограничений не имеет. Основное при программировании на ASM - правильность-оптимальность
кода, быстродействие. А читабельность определяется "воспитанностью" программиста.
CPP код, в конечном счете, компилируется в ASM код с последующей трансляцией в машинный.
И если посмотреть на этот ASM, то там масса JMP, оноже - как-бы GOTO.
Основная идея "шельмования" goto - ухудшение стрктурированности и читабельности кода.

Я пользуюсь (иногда) такой методой заменяющей goto и не ухудшающей читабельность.

Код
while(1)
{
___if( xxx )  
______yyyyy;
____else
_____ break;    
      . . . . итд много кода (кроме циклов)

____break;
}

Вообще, насколько такой прием корректен ?
DASM
Нечитабельно. Уж лучше goto тогда уже имхо.
еще из этой оперы - плохо, когда в функции много точек выхода
вместо
Код
if (cond1)
    return 1;
else if (cond2)
{
    if (cond3)
        return 2;
    else return 3;
}
else
    return 0;

пишу
Код
uint8_t rc = 0;
if (cond1)
    rc = 1;
else if (cond2)
{
    if (cond3)
        rc =  2;
    else rc = 3;
}
return rc;
k155la3
Цитата(DASM @ Nov 11 2017, 21:16) *

А Goto симпатишная sm.gif
nice_vladi
Цитата(k155la3 @ Nov 11 2017, 17:27) *
Указатели на функции использовать можно, если в этом есть смысл или необходимость.
Например, Вы выбираете определенное действие в некой последовательности, из набора, скажем, 100 функций.
Причем эти наборы разные, и/или могут вычисляться.
Приечем Вы можете в любое время заменить любой из указателей, не изменяя основного алгоритма.
В ЭТОМ случае создаете массив указателей на функциии и вызов(а) делеаете по индексу, "переключая" или вычисляя нужный.
Это скорее метода для С.
------
А то что Вы спрашиваете, по-моему, и так обеспечивается CPP операторами точка и -->
при вызове метода (функции), своего или унаследованного.


Да, обеспечивается. Но при обращении "сверху вниз". Допустим, из основного окна интерфейса в дочерние, создаваемые в нем. Мне же нужно наоборот, ходить "снизу вверх". Допустим, из созданных вкладок интерфейса в их "создателя", основное окно.

Имел опыт работы с Qt - там применялись сигнал-слоты. В Visual studio нашел подобное решение - это __event. Пользуюсь ими. Но в процессе поиска (до того, как обнаружил ивенты) пытался как-то по-другому достигнуть результата. Тут и начали возникать вопросы с указателями на функции.
DASM
не очень понятно, что нужно. Ну так вызывайте функцию родителя прямо, зачем __event?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.