std::function与回调类
虽不易 2018-09-09 17:51:04
收藏 1
文章标签: [function 回调类](https://so.csdn.net/so/search/s.do?q=function 回调类&t=blog&o=vip&s=&l=&f=&viparticle=)
版权
<article class="baidu_pl">
std::function是c++11中提供的Callable类,所以本篇文章中整理了function的使用方式,及以function为基础封装回调类。
1. function的使用
#include <iostream>
#include <string>
#include <functional>
int add(int a, int b)
{
return a + b;
}
class EchoMessage
{
public:
void echoMessage(const string& msg)
{
std::cout << msg << std::endl;
}
}
void test()
{
// 普通函数绑定
function<int(int, int)> f_add = &add;
int sum = f_add(1, 2);
// 对象成员函数绑定,注意收个函数为类对象引用或指针;
function<void(EchoMessage&, const string&)> f_echo = &EchoMessage::echoMessage;
EchoMessage em;
f_echo(em, "Hello");
// 参数绑定
function<void(const string&)> f_echo1 = bind(&EchoMessage::echoMessage, em, placeholders::_1);
f_echo1("Hello");
}
2. 基于function的回调类
通过将对象指针及成员函数指针保存在回调类型的成员中,在执行某个执行流中调用执行成员函数函数,即可实现函数的回调。依据上述思路,参考muduo库中的实现,对回调类的封装如下。注意执行回到函数的返回值为void。
#include <functional>
#include <iostream>
#include <memory>
using namespace std;
template <typename Cls, typename... Args>
class WeakCallback
{
public:
// 将类指针,作为首个参数,构造function回调;
using callable = function<void(Cls*, Args...)>;
// 入参弱指针类型,从外部接管对象,其生命周期与WeakCallback对象的声明周期一致
WeakCallback(const weak_ptr<Cls>& ptr_obj, const callable& cb)
: ptr_obj_(ptr_obj),
cb_(cb)
{
}
// 重载括号操作符
void operator()(Args&&... args)
{
// 此处必须转换为shared_ptr,否则会导致弱指针退出作用域而被析构
shared_ptr<Cls> ptr_obj(ptr_obj_.lock());
if(ptr_obj)
{
cb_(ptr_obj.get(), std::forward<Args>(args)...);
}
}
private:
weak_ptr<Cls> ptr_obj_;
callable cb_;
};
template<typename CLASS, typename... ARGS>
WeakCallback<CLASS, ARGS...> makeWeakCallback(const shared_ptr<CLASS>& object, void (CLASS::*mem_func)(ARGS...))
{
return WeakCallback<CLASS, ARGS...>(object, mem_func);
}
// 测试代码
struct Foo
{
public:
Foo(int num) : num_(num) {}
void printAdd(int a)
{
std::cout << "==printAdd: " << (num_ + a) << std::endl;
}
private:
int num_;
};
int main()
{
shared_ptr<Foo> ptr_foo(new Foo(5));
auto wcb = makeWeakCallback(ptr_foo, &Foo::printAdd);
wcb(5);
return 0;
}
上述代码的最主要功能就是实现第一个回调对象与对象成员函数在调用时的绑定,因c++本身支持参数绑定功能,所以可以有如下实现方式:
template <typename Clz, typename... Args>
using BindedWeakCallback = function<void(Args...)>;
template<typename CLASS, typename... ARGS>
BindedWeakCallback<CLASS, ARGS...> makeWeakCallbackWithBind(const shared_ptr<CLASS>& object,
void (CLASS::*mem_func)(ARGS...))
{
return bind(mem_func, object.get(), placeholders::_1);
}
int main()
{
shared_ptr<Foo> ptr_foo(new Foo(5));
auto wcb = makeWeakCallbackWithBind(ptr_foo, &Foo::printAdd);
wcb(5);
return 0;
}
</article>