项目中有时候能遇到一些回调函数,于是思考其实现方法,顺便找了一下其他实现方法,简单总结一下:
函数指针
关于函数指针,有趣的是: Why do function pointer definitions work with any number of ampersands ‘&’ or asterisks ‘*’?
下面直接看 demo
,这里模拟的是外部 lib
及使用的的使用方法:
//CallBack 1
/***************** in the External library ************************/
typedef void(*CallbackFun)();
void testfun_API(CallbackFun pCallBackFun)
{
qDebug() << "testfun_API()";
pCallBackFun();
}
/***************** Use code ********************/
void Callback(){
qDebug() << "Callback()";
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
testfun_API(Callback);
return a.exec();
}
下面这种写法也是对的:
/***************** in the External library ************************/
void testfun_API(void(*pCallBackFun)())
{
qDebug() << "testfun_API()";
pCallBackFun();
}
/***************** Use code ********************/
void Callback(){
qDebug() << "Callback()";
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
testfun_API(Callback);
return a.exec();
}
C++虚函数
借助 C++
的虚函数,将回调函数(虚函数)交由使用者实现,这里模拟一个蓝牙类,它有一个 Scan()
与扫描回调函数。
/********************in the External library ********************************/
class Bluetooth : public QObject
{
Q_OBJECT
public:
explicit Bluetooth(QObject *parent = nullptr);
void Scan();
virtual void ScanCallBack();
}
void Bluetooth::Scan(){
qDebug() << "Bluetooth::Scan()...";
ScanCallBack();
}
void Bluetooth::ScanCallBack(){
qDebug() << "Bluetooth::ScanCallBack()";
}
/******************** Use code *****************************/
class Bluetooth_example : public Bluetooth
{
Q_OBJECT
public:
Bluetooth_example();
void ScanCallBack();
};
void Bluetooth_example::ScanCallBack(){
qDebug() << "Bluetooth_example::ScanCallBack()";
}
//CallBack 2
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Bluetooth_example *example = new Bluetooth_example;
example->Scan();
return a.exec();
}
bind & function
这是 C++ 11 的新特性之一。
bind
是这样一种机制,它可以将参数绑定于可调用对象,产生一个新的可调用实体,这种机制在函数回调时颇为有用。
通过 std::function
对C++
中各种可调用实体(普通函数、Lambda
表达式、函数指针、以及其它函数对象等)的封装,形成一个新的可调用的 std::function
对象;让我们不再纠结那么多的可调用实体。
// 该写法替代 typedef void(*CallbackFun)();
typedef std::function< void()> CallbackFun;
// 该方法获取成员函数
std::function<void()> mtestAPI = std::bind(testfun_API);
mtestAPI();
有了这个以后没我们可以在类中定义一个回调函数变量,通过set方法设置。参见:使用C++11 std::bind和std::function实现回调机制。
强烈推荐 深入 C++ 回调 ,一时半会没弄明白,留着过年吧~