реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Указатели на функции С++, Корректность применения
nice_vladi
сообщение Nov 11 2017, 10:08
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 53
Регистрация: 7-09-16
Из: Томск
Пользователь №: 93 239



Всем привет.

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

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

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

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

Visual Studio 2013

Спасибо! biggrin.gif
Go to the top of the page
 
+Quote Post
gosha-z
сообщение Nov 11 2017, 15:51
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 327
Регистрация: 30-10-05
Пользователь №: 10 288



Навскидку в голову приходит только аккуратное слежение за calling convention.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 11 2017, 16:00
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
k155la3
сообщение Nov 11 2017, 16:27
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



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


Go to the top of the page
 
+Quote Post
DASM
сообщение Nov 11 2017, 17:16
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



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 лет над. Например венегрская нотация - вредная вещь, а количество комментариев к коду - должно стремиться к нулю
Go to the top of the page
 
+Quote Post
_pv
сообщение Nov 11 2017, 17:37
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(DASM @ Nov 11 2017, 23:16) *
"из набора, скажем, 100 функций." явно ошибка проектирования, так не бывает.

ну вот есть какое-нибудь устройство с кучей регистров.
при получении пакета с чтением/записью регистра вместо большого switch имхо проще руками сделать массив функций из которого нужная позовётся по адресу регистра.
пусть этот массив и будет забит в основном стандартной заглушкой, если там хотя бы десяток другой различных функций наберётся уже красивее выглядеть будет.
Go to the top of the page
 
+Quote Post
DASM
сообщение Nov 11 2017, 18:04
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



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

А свитч то зачем? Регистры все разных типов, что их надо устанавливать совершенно разным кодом?
Go to the top of the page
 
+Quote Post
_pv
сообщение Nov 11 2017, 18:46
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



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

ну пусть это будут регистры которые отвечают за всякую разную периферию, соответственно при записи определённых регистров надо делать определённые действия, а не просто записать значение в память.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Nov 11 2017, 22:28
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(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;
}

Вообще, насколько такой прием корректен ?
Go to the top of the page
 
+Quote Post
DASM
сообщение Nov 11 2017, 22:54
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Нечитабельно. Уж лучше 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;
Go to the top of the page
 
+Quote Post
k155la3
сообщение Nov 11 2017, 23:26
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(DASM @ Nov 11 2017, 21:16) *

А Goto симпатишная sm.gif
Go to the top of the page
 
+Quote Post
nice_vladi
сообщение Nov 13 2017, 03:10
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 53
Регистрация: 7-09-16
Из: Томск
Пользователь №: 93 239



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


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

Имел опыт работы с Qt - там применялись сигнал-слоты. В Visual studio нашел подобное решение - это __event. Пользуюсь ими. Но в процессе поиска (до того, как обнаружил ивенты) пытался как-то по-другому достигнуть результата. Тут и начали возникать вопросы с указателями на функции.
Go to the top of the page
 
+Quote Post
DASM
сообщение Nov 13 2017, 07:52
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



не очень понятно, что нужно. Ну так вызывайте функцию родителя прямо, зачем __event?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 15th June 2025 - 12:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.01497 секунд с 7
ELECTRONIX ©2004-2016