На вашем месте я бы не использовал указатели функций для выполнения этой задачи. Оставьте эту опцию гуру;)
В Boost есть красивая библиотека, которая называется сигналов . Это делает вашу жизнь проще! Это пример использования:
#include <iostream>
#include <boost/bind.hpp>
#include <boost/signal.hpp>
using namespace std;
using namespace boost;
struct A
{ void A_action() { cout << "A::A_action();" << endl; } };
struct B
{ void B_action() { cout << "B::B_action();" << endl; } };
struct C
{ void C_action() { cout << "C::C_action();" << endl; } };
struct X
{
// Put all the functions you want to notify!
signal<void()> list_of_actions;
void do_something()
{
std::cout << "Hello I am X!" << endl;
list_of_actions(); // send notifications to all functions in the list!
}
};
int main()
{
X x;
A a;
B b;
C c;
x.list_of_actions.connect(bind(&A::A_action, a));
x.list_of_actions.connect(bind(&B::B_action, b));
x.list_of_actions.connect(bind(&C::C_action, c));
x.do_something();
}
Будет напечатано:
Hello I am X!
A::A_action();
B::B_action();
C::C_action();
Вот как это работает.
Сначала вы объявляете место, в котором находятся делегаты:
signal<void()> list_of_actions;
Затем вы «подключаете» его к любой группе функций / функторов / вызываемых объектов, которые вы хотите вызвать.
x.list_of_actions.connect(bind(&A::A_action, a));
x.list_of_actions.connect(bind(&B::B_action, b));
x.list_of_actions.connect(bind(&C::C_action, c));
Обратите внимание, что я использовал bind
. Итак, тип функций в list_of_actions одинаков, но мы можем подключить его к разным типам классов. Итак:
bind(&A::A_action, a)
Эта вещь производит вызываемую вещь типа void ()
, как мы объявили тип list_of actions
ранее. Конечно, вы указываете экземпляр, к которому хотите применить эту функцию-член, во втором параметре ..
Если вы занимаетесь многопоточными вещами, используйте сестру сигналов2 .
Надеюсь, это поможет.