Перейти к содержанию
    

Указатели на функции С++

Всем привет.

 

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

 

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

 

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

потому-что - потому-что.

 

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

 

Visual Studio 2013

 

Спасибо! :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Причем эти наборы разные, и/или могут вычисляться.

Приечем Вы можете в любое время заменить любой из указателей, не изменяя основного алгоритма.

В ЭТОМ случае создаете массив указателей на функциии и вызов(а) делеаете по индексу, "переключая" или вычисляя нужный.

Это скорее метода для С.

------

А то что Вы спрашиваете, по-моему, и так обеспечивается CPP операторами точка и -->

при вызове метода (функции), своего или унаследованного.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 лет над. Например венегрская нотация - вредная вещь, а количество комментариев к коду - должно стремиться к нулю

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

ну вот есть какое-нибудь устройство с кучей регистров.

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну вот есть какое-нибудь устройство с кучей регистров.

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

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

А свитч то зачем? Регистры все разных типов, что их надо устанавливать совершенно разным кодом?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А свитч то зачем? Регистры все разных типов, что их надо устанавливать совершенно разным кодом?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

. . .

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

. . . .

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

Хотя сам делал с использованием указателей на ф-ии систему многоуровневого и многопунктного меню,

по той причине, чтобы все меню было видно компактно, в виде одного массива-таблицы структур.

Переход между пунктами и между меню - с использованием индексов. Проверено на практике.

С интерпретатором надо будет юлозить по стуктурированному коду.

Еще один из вариантов использования - реализация автоматов или томуподобного.

(база индекса - состояние, смещение - сигнал). Опятьже - например. То что делается стандартно на case-switch.

Но думаю "детали" ТС неинтересны :)

 

ps - таблицы виртуальных функций.

Я и уточняю у ТС, "онож уже есть" :)

 

. . . Приведу пример: есть такая вещь, как goto: Но ее применять не рекомендуется,

потому-что - потому-что.

. . .

Для программ на ASM использование безусловного перехода JMP addr - аналога goto

никаких ограничений не имеет. Основное при программировании на ASM - правильность-оптимальность

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

CPP код, в конечном счете, компилируется в ASM код с последующей трансляцией в машинный.

И если посмотреть на этот ASM, то там масса JMP, оноже - как-бы GOTO.

Основная идея "шельмования" goto - ухудшение стрктурированности и читабельности кода.

 

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

 

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

____break;
}

Вообще, насколько такой прием корректен ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нечитабельно. Уж лучше 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;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А Goto симпатишная :)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Причем эти наборы разные, и/или могут вычисляться.

Приечем Вы можете в любое время заменить любой из указателей, не изменяя основного алгоритма.

В ЭТОМ случае создаете массив указателей на функциии и вызов(а) делеаете по индексу, "переключая" или вычисляя нужный.

Это скорее метода для С.

------

А то что Вы спрашиваете, по-моему, и так обеспечивается CPP операторами точка и -->

при вызове метода (функции), своего или унаследованного.

 

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

 

Имел опыт работы с Qt - там применялись сигнал-слоты. В Visual studio нашел подобное решение - это __event. Пользуюсь ими. Но в процессе поиска (до того, как обнаружил ивенты) пытался как-то по-другому достигнуть результата. Тут и начали возникать вопросы с указателями на функции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не очень понятно, что нужно. Ну так вызывайте функцию родителя прямо, зачем __event?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...