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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
KilloN
3 / 3 / 0
Регистрация: 27.05.2012
Сообщений: 26
#1

Сохранение функций в переменных и дальнейший их вызов - C++

27.06.2012, 21:24. Просмотров 994. Ответов 15
Метки нет (Все метки)

Я тут вспомнил, когда программил в ActionScript 3, там была такая особенность использовать переменные с типом функция. Это очень удобная вещь)) Интересно возможно ли проделать такое же в С++?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <fstream>
#include <string>
 
using namespace std;
 
void ddd(int i){
    i++;
}
 
int main() {
    int a=10;
    void* fff;
    fff = (void*)&ddd;
 
    *fff(a);
    
    cout<<a;
 
    return 0;
}
Код ошибку выдаёт только в *fff(a); . Однако ссылку на функцию получить возможно и возвращает она непонятную хрень void (__cdecl *)(int), если бы ф-я не принимала параметров, тогда она возвращала бы void (__cdecl *)(void), cdecl насколько помню - это соглашение о передаче параметров ф-и...
Т.Е. основной вопрос, возможно ли её вызвать?))
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.06.2012, 21:24
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Сохранение функций в переменных и дальнейший их вызов (C++):

Итерационные циклы,Определение и вызов функций,Использование библиотечных функций stdio.h - C++
Помогите решить задания: 1.Дано натуральное число n. Найти разность между первой цифрой этого числа и суммой всех остальных. ...

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

Вызов функций внутри других функций - C++
#include &quot;stdafx.h&quot; #include &quot;stdio.h&quot; #include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;iomanip&gt; using namespace std; ...

Вызов функций - C++
В одномерном массиве, состоящем из п целых элементов, вычислить: 1) номер максимального элемента массива; 2) произведение элементов...

Вызов функций - C++
Можно ли программно вызвать все функции записанные в файле?

Вызов функций - C++
Можно ли преобразовать строку, вводимою с консоли в вызов функции? То есть к примеру у меня предопределено несколько функций. С консоли...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
gray_fox
What a waste!
1511 / 1214 / 69
Регистрация: 21.04.2012
Сообщений: 2,550
Завершенные тесты: 3
27.06.2012, 21:28 #2
Цитата Сообщение от KilloN Посмотреть сообщение
void* fff; fff = (void*)&ddd;
C++
1
void (*fff)(int) = ddd;
Цитата Сообщение от KilloN Посмотреть сообщение
*fff(a);
C++
1
fff(a);
Петррр
5949 / 3386 / 337
Регистрация: 28.10.2010
Сообщений: 5,926
27.06.2012, 21:33 #3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
 
void inc(int& val)
{
    ++val;
}
 
int main()
{
    int a = 10;
    void (*function)(int&) = &inc;
    std::cout << a << std::endl;
    function(a);
    std::cout << a << std::endl;
    system("pause");
    return 0;
}
KilloN
3 / 3 / 0
Регистрация: 27.05.2012
Сообщений: 26
27.06.2012, 21:39  [ТС] #4
О спасибо парни))
В обычных учебниках по С++ такого не пишут
Петррр
5949 / 3386 / 337
Регистрация: 28.10.2010
Сообщений: 5,926
27.06.2012, 21:42 #5
KilloN, еще как пишут.
KilloN
3 / 3 / 0
Регистрация: 27.05.2012
Сообщений: 26
27.06.2012, 21:45  [ТС] #6
Цитата Сообщение от Петррр Посмотреть сообщение
KilloN, еще как пишут.
У меня ООП С++ от Р.Лафоре

А в какой книге подробно описаны тонкости языка?
Петррр
5949 / 3386 / 337
Регистрация: 28.10.2010
Сообщений: 5,926
27.06.2012, 21:51 #7
KilloN, это есть во всех нормальных книгах:
Страуструп Б. Язык Программирования С++ - 2011
Глава 7.7.

Харви М. Дейтел, Пол Дж. Дейтел - Как программировать на C++ (пятое издание)
Глава 8.12
KilloN
3 / 3 / 0
Регистрация: 27.05.2012
Сообщений: 26
27.06.2012, 22:05  [ТС] #8
Это точно, видимо я учился по обрубленной литературе...
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6447 / 3094 / 306
Регистрация: 04.12.2011
Сообщений: 8,567
Записей в блоге: 4
27.06.2012, 22:31 #9
Цитата Сообщение от KilloN Посмотреть сообщение
видимо я учился
Указатель на функцию, хорошее дело, если совпадают сигнатуры (тип возвращаемого значения, тип и порядок следования аргументов).
Если сигнатуры не совпадают - можно перегрузить имя функции.
Еще интересно, может быть переопределение виртуальных функций при наследовании классов.
Шаблонные функции удобны, если алгоритм (код) одинаков и отличие, только в обрабатываемых типах.
Об этом пишут везде. Именно в C++ - и есть из чего выбрать, как определить и вызвать код.
KilloN
3 / 3 / 0
Регистрация: 27.05.2012
Сообщений: 26
27.06.2012, 23:31  [ТС] #10
Цитата Сообщение от IGPIGP Посмотреть сообщение
Указатель на функцию, хорошее дело, если совпадают сигнатуры (тип возвращаемого значения, тип и порядок следования аргументов).
Но можно же использовать функции с переменным числом аргументов))
Это частично решает проблему))

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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
 
void inc(int& val)
{
    ++val;
}
 
int inc2(int val)
{
    return ++val;
}
 
int main()
{
    int a = 10;
    int b = 66;
 
    void (*func);
    func = &inc;
 
    ((void (__cdecl *)(int&))func)(a);
 
    std::cout << a << std::endl;
 
    func = &inc2;
    b += ((int (__cdecl *)(int))func)(a);
 
    std::cout << a << std::endl;
    std::cout << b << std::endl;
 
    system("pause");
    return 0;
}
}
Ахренеть я тут намудрил
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6447 / 3094 / 306
Регистрация: 04.12.2011
Сообщений: 8,567
Записей в блоге: 4
27.06.2012, 23:52 #11
Цитата Сообщение от KilloN Посмотреть сообщение
Если исп. ссылку на тип void...
использовать - ключевое слово.)
Объявить, можно многое. А потом определить перед обращением. Когда Вы производите приведение к типу, - определяете указатель. Там же приходится указать тип и порядок следования аргументов. Хотя конечно, Вы правы это расширяет возможности вызова через указатель. Главное не запутаться. Ведь в месте вызова, должны быть известны все переменные передаваемые через аргументы и... это реализуемо.
KilloN
3 / 3 / 0
Регистрация: 27.05.2012
Сообщений: 26
28.06.2012, 00:08  [ТС] #12
Дело в том, что таким образом очень удобно вызывать нужные ф-и, которые находятся в других модулях. Не нужно используя глобальные переменные включать заголовки других модулей, затем создавать переменную типа ссылка на какой либо класс, затем вызывать ф-ю... исп. эту ссылку... слишком муторно
К тому же как я выяснил не всегда получается, у меня в проекте я исп. wxWidgets, и там почему то ругается. когда я пыт. создать глоб. ссылку на класс(хоть ты тресни не хочит и всё). Хотя возможно ошибка была из-за того что первый заголовочный файл ссылается на второй а второй на первый -> В конце концов я решил что это самый удобный способ с указателями на ф-ю

Добавлено через 2 минуты
ИМХО
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
28.06.2012, 00:13 #13
std::function / lambda функции из С++11.
boost::function из буста.
Намного удобнее чем указатели на функции фигачить.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6447 / 3094 / 306
Регистрация: 04.12.2011
Сообщений: 8,567
Записей в блоге: 4
28.06.2012, 00:22 #14
KilloN, в Вашем примере void inc объявлена и определена, в файле, поэтому я и не понял тогда, при чем соглашение по вызову... Наверное можно и так.
KilloN
3 / 3 / 0
Регистрация: 27.05.2012
Сообщений: 26
28.06.2012, 03:15  [ТС] #15
Цитата Сообщение от ForEveR Посмотреть сообщение
std::function / lambda функции из С++11.
boost::function из буста.
Намного удобнее чем указатели на функции фигачить.
Ты имел в виду что то типа этого?
C++
1
2
3
4
5
6
void foo(int, int) {;}
 
boost::function<void (int, int)> f1;
f1 = foo;
// или
f1 = &foo;
Добавлено через 2 часа 27 минут
Всё же я лохонулcя, как не пытался у меня не получилось присвоить функцию класса обычной переменной. C обычными ф-ями всё просто. Возможно получилось бы статической переменной присвоить, но это совсем не то!!!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class rrr{
public:
int i;
    void xxx(int j){
        i=j;
    }
};
int main()
{
    rrr r;
    void (__thiscall rrr::* www)(int);
    r.xxx(10);
 
    cout<<r.i<<endl;
 
    www = &rrr::xxx;
    www(99);// не пашет error
    
    cout<<r.i<<endl;
 
    system("pause");
    return 0;
}
Наверное это невозможно, функция каким либо образом должна иметь доступ только к данным определённого созданного объекта...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.06.2012, 03:15
Привет! Вот еще темы с ответами:

Вызов функций - C++
Для чего нужны stdcall и cdecl? и как они работают? Спасибо=)

Вызов функций - C++
Всем привет! Слушайте, в проге которую я сейчас пишу несколько функций, и мне нужно по ходу работы программы вызывать другие функции. Из...

Сохранение переменных - C++
Мне нужно, что бы переменная сохранялась, тоисть я ввёл cin &gt;&gt; a; и закрыл, а когда открыл что бы она мне вывелась.

Объявление и вызов функций? - C++
Из двух книжек ни фига не понял как вызывать эти чёртовы функции, а без них никуда. Помогите пожалуйста. в этом примере: ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
28.06.2012, 03:15
Ответ Создать тему
Опции темы

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