/* C语言用全局函数实现回调 */
#include <stdio.h>
typedef void (*pfunc)(void);
void callback(void) {
printf("hello\n");
}
void caller(pfunc p)
{
(*p)();
}
int main(void)
{
caller(&callback);
}
/* c++用类成员函数实现回调 */
#include <stdio.h>
class CCallback
{
public:
void Func(void)
{
printf("hello\n");
}
};
typedef void (CCallback::*pMemberFunc)(int);
void Caller(CCallback* pObj,pMemberFunc p)
{
(pObj->*p)(1);
}
int main(int argc, char* argv[])
{
CCallback obj;
Caller(&obj,&CCallback::Func);//非静态成员函数须通过对象来访问
Signal/Slots
在C++中信号与槽才是回调的完美解决方案,本质是一个观察者模式
#include <vector>
#include <iostream>
using namespace std;
template<typename T, typename T1>
class slot
{
public:
slot(T* pObj, void (T::*pMemberFunc)(T1))
{
m_pObj = pObj;
m_pMemberFunc = pMemberFunc;
}
void Execute(T1 para)
{
(m_pObj->*m_pMemberFunc)(para);
}
private:
T* m_pObj;
void (T::*m_pMemberFunc)(T1);
};
//signal类有两个模板参数,一个是类的类型,一个是函数参数类型
template<typename T, typename T1>
class signal
{
public:
void bind(T* pObj, void (T::*pMemberFunc)(T1 para))
{
m_slots.push_back(new slot<T, T1>(pObj, pMemberFunc));
}
~signal()
{
vector<slot<T, T1>* >::iterator ite = m_slots.begin();
for (; ite != m_slots.end(); ite++)
{
delete *ite;
}
}
void operator()(T1 para)
{
vector<slot<T, T1>* >::iterator ite = m_slots.begin();
for (; ite != m_slots.end(); ite++)
{
(*ite)->Execute(para);
}
}
private:
vector<slot<T, T1>* > m_slots;
};
class receiver
{
public:
void callback1(int a)
{
cout << "receiver1: " << a << endl;
}
void callback2(int a)
{
cout << "receiver2: " << a << endl;
}
};
class sender
{
public:
sender() : m_value(0) {}
int get_value()
{
return m_value;
}
void set_value(int new_value)
{
if (new_value != m_value)
{
m_value = new_value;
m_sig(new_value);//重载运算符()的使用
}
}
signal<receiver, int> m_sig;
private:
int m_value;
};
int main(int argc, char** arg)
{
receiver r;
sender s;
s.m_sig.bind(&r, &receiver::callback1);
s.m_sig.bind(&r, &receiver::callback2);
s.set_value(1);
s.set_value(1);
return 0;
}
//receiver1: 1
//receiver2: 1
#include <vector>
#include <iostream>
using namespace std;
template<typename T1>
class slotbase
{
public:
virtual void Execute(T1 para) = 0;
};
template<typename T, typename T1>
class slotimpl : public slotbase<T1>
{
public:
slotimpl(T* pObj, void (T::*pMemberFunc)(T1))
{
m_pObj = pObj;
m_pMemberFunc = pMemberFunc;
}
virtual void Execute(T1 para)
{
(m_pObj->*m_pMemberFunc)(para);
}
private:
T* m_pObj;
void (T::*m_pMemberFunc)(T1);
};
template<typename T1>
class slot
{
public:
template<typename T>
slot(T* pObj, void (T::*pMemberFunc)(T1))
{
m_pSlotbase = new slotimpl<T, T1>(pObj, pMemberFunc);
}
~slot()
{
delete m_pSlotbase;
}
void Execute(T1 para)
{
m_pSlotbase->Execute(para);
}
private:
slotbase<T1>* m_pSlotbase;
};
template<typename T1>
class signal
{
public:
template<typename T>
void bind(T* pObj, void (T::*pMemberFunc)(T1 para))
{
m_slots.push_back(new slot<T1>(pObj, pMemberFunc));
}
~signal()
{
vector<slot<T1>* >::iterator ite = m_slots.begin();
for (; ite != m_slots.end(); ite++)
{
delete *ite;
}
}
void operator()(T1 para)
{
vector<slot<T1>* >::iterator ite = m_slots.begin();
for (; ite != m_slots.end(); ite++)
{
(*ite)->Execute(para);
}
}
private:
vector<slot<T1>* > m_slots;
};
#define CONNECT(sender,signal,receiver,slot) sender.signal.bind(receiver,slot)
class receiver
{
public:
void callback1(int a)
{
cout << "receiver1: " << a << endl;
}
};
class receiver2
{
public:
void callback2(int a)
{
cout << "receiver2: " << a << endl;
}
};
class sender
{
public:
sender() : m_value(0) {}
int get_value()
{
return m_value;
}
void set_value(int new_value)
{
if (new_value != m_value)
{
m_value = new_value;
m_valueChanged(new_value);
}
}
signal<int> m_valueChanged;
private:
int m_value;
};
int main(int argc, char** arg)
{
receiver r;
receiver2 r2;
sender s;
CONNECT(s, m_valueChanged, &r, &receiver::callback1);
CONNECT(s, m_valueChanged, &r2, &receiver2::callback2);
s.set_value(1);
return 0;
}
//receiver1: 1
//receiver2: 1