Как описать функцию член класса которая вовращает указатель на функцию член класса?
Здраствуйте. Описать это словами трудно, проще привести простенький пример кода
#include <iostream>
using namespace std;
class FlipFloper
{
public:
FlipFloper(): action(&FlipFloper::flip) {}
void run()
{
action=(this->*action)();
}
private:
(FlipFloper::*)() (FlipFloper::*action)();
(FlipFloper::*)() flip()
{
cout << "flip" << endl;
return &FlipFloper::flop; // возвращаем указатель на flop
}
(FlipFloper::*)() flop()
{
cout << "flop" << endl;
return &FlipFloper::flip; // возвращаем указатель на flip
}
};
int main()
{
FlipFloper ff;
for(int i=0;i<10;++i)
{
ff.run();
}
return 0;
}
action - переменная-указатель которая поочередно указывает то на функцию flip то на функцию flop, при создании екземпляра инициализируется значением указателя на flip. соответственно если в цикле вызывать run() то на екран по очереди пойдут строки "flip" и "flop". компилятор - g++ спасибо.
Ответы (1 шт):
Это невозможно сделать напрямую, но есть обходной способ, см. конец ответа.
Предположим, у вас есть:
struct A
{
void foo() {}
};
И вы хотите дописать внутрь A функцию bar, которая возвращает указатель-на-член на foo.
Это пишется так:
void (A::*bar())() {return &A::foo;}
Тип расшифровывается так:
bar bar - это
bar() функция без параметров, возвращающая
A::*bar() указатель-на-член класса A, имеющий тип: (
(A::*bar()) ...
(A::*bar())() функция без параметров, возвращающая
void (A::*bar())() void )
Теперь, пусть вы хотите написать функцию baz, возвращающую указатель-на-член на bar.
Она пишется так: void (A::*(A::*baz())())() {return &A::bar;}. Расшифровать тип предлагается самостоятельно.
Можно заметить, что если функция X возвращает указатель на функцию Y, то тип X длиннее, чем тип Y. Поэтому две функции не могут напрямую возвращать указатели друг на друга.
Решение есть - положить указатель во вспомогательную структуру, и из функций возвращать эту структуру.
#include <iostream>
struct FlipFloper
{
struct P
{
P (FlipFloper::*ptr)();
};
P action{&FlipFloper::flip};
void run()
{
action = (this->*action.ptr)();
}
P flip()
{
std::cout << "flip" << std::endl;
return {&FlipFloper::flop};
}
P flop()
{
std::cout << "flop" << std::endl;
return {&FlipFloper::flip};
}
};
int main()
{
FlipFloper ff;
for (int i = 0; i < 10; i++)
ff.run();
return 0;
}