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

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

Восстановить пароль Регистрация
 
KilloN
3 / 3 / 0
Регистрация: 27.05.2012
Сообщений: 26
27.06.2012, 21:24     Сохранение функций в переменных и дальнейший их вызов #1
Я тут вспомнил, когда программил в 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++
C++ Вызов функций
Вызов функций C++
Итерационные циклы,Определение и вызов функций,Использование библиотечных функций stdio.h C++
Затраты на вызов функций C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 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);
Петррр
 Аватар для Петррр
5917 / 3354 / 333
Регистрация: 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
О спасибо парни))
В обычных учебниках по С++ такого не пишут
Петррр
 Аватар для Петррр
5917 / 3354 / 333
Регистрация: 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, еще как пишут.
У меня ООП С++ от Р.Лафоре

А в какой книге подробно описаны тонкости языка?
Петррр
 Аватар для Петррр
5917 / 3354 / 333
Регистрация: 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
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,722
Записей в блоге: 3
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
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,722
Записей в блоге: 3
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
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
28.06.2012, 00:13     Сохранение функций в переменных и дальнейший их вызов #13
std::function / lambda функции из С++11.
boost::function из буста.
Намного удобнее чем указатели на функции фигачить.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6172 / 2901 / 284
Регистрация: 04.12.2011
Сообщений: 7,722
Записей в блоге: 3
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, 10:24     Сохранение функций в переменных и дальнейший их вызов
Еще ссылки по теме:

Вызов функций C++
C++ Вызов функций внутри других функций
C++ Вызов функций

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

Или воспользуйтесь поиском по форуму:
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
28.06.2012, 10:24     Сохранение функций в переменных и дальнейший их вызов #16
Сообщение было отмечено автором темы, экспертом или модератором как ответ
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <functional>
 
class C
{
public:
   void print() const { std::cout << "Print" << std::endl; }
};
 
typedef std::function<void(const C*)> function;
 
int main()
{
   C obj;
   function f = &C::print;
   f(&obj);
}
http://liveworkspace.org/code/33b4d4...a1fb5b37296f79
Не самый лучший вариант.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <functional>
 
class C
{
public:
   void print() const { std::cout << "Print" << std::endl; }
};
 
int main()
{
   C obj;
   auto f = std::bind(&C::print, &obj);
   f();
}
http://liveworkspace.org/code/4f46c2...025719c0b10bc6
Хороший вариант.
Yandex
Объявления
28.06.2012, 10:24     Сохранение функций в переменных и дальнейший их вызов
Ответ Создать тему
Опции темы

Текущее время: 12:00. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru