怎么绑定成员函数(之前绑定的是自由函数):
1.bind方式(不推荐)
#include <iostream>
#include <boost\asio.hpp>
#include <boost\bind.hpp>
#include <boost\date_time\posix_time\posix_time.hpp>
class printer {
public:
printer(boost::asio::io_service &io) :
timer_(io, boost::posix_time::seconds(1)),
count_(0)
{
timer_.async_wait(boost::bind(&printer::print, this));
}
~printer() {
std::cout << "Final count is " << count_ << std::endl;
}
void print() {
// ...d0 something ...
std::cout << "in print ..." << std::endl;
}
private:
boost::asio::deadline_timer timer_;
int count_;
};
int main()
{
// 我们的程序和操作系统底层之间的一个相互传递的枢纽
// 会把事件按照一定方式进行处理;
boost::asio::io_service io;
printer p(io);
// 开始运行;
io.run();
std::cout << "mian finish run \n" << std::endl;// 提示下main函数已经结束了
system("pause");// 让VS控制台程序不会一闪而过;
return 0;
}
如果是用STL的bind来绑定
#include <functional>//跟函数相关的都在这里头
把bind 改成 std::bind
2. lambda(推荐)
如果是用lambda来绑定
不用引入头文件
改成 timer_.async_wait([this](const auto&){this->print();});
const auto&是函数自带的参数,boost::system::error_code,是一个错误码,用auto来替代的这种方式,要求C++14以上版本才能编译
#include <iostream>
#include <boost\asio.hpp>
#include <boost\date_time\posix_time\posix_time.hpp>
class printer {
public:
printer(boost::asio::io_service &io) :
timer_(io, boost::posix_time::seconds(1)),
count_(0)
{
timer_.async_wait([this](const boost::system::error_code&) {this->print();});
}
~printer() {
std::cout << "Final count is " << count_ << std::endl;
}
void print() {
// ...d0 something ...
std::cout << "in print ..." << std::endl;
}
private:
boost::asio::deadline_timer timer_;
int count_;
};
int main()
{
// 我们的程序和操作系统底层之间的一个相互传递的枢纽
// 会把事件按照一定方式进行处理;
boost::asio::io_service io;
printer p(io);
// 开始运行;
io.run();
std::cout << "mian finish run \n" << std::endl;// 提示下main函数已经结束了
system("pause");// 让VS控制台程序不会一闪而过;
return 0;
}
bind返回的是 function<void(const boost::system::error_code)>
lambda返回的是lambda
区别:
function是真正生成一个类的实体,有默认的回调,默认的赋值,操作等。。而且不能在编译器展开,sizeof也相对要大
lambda可以在编译器展开,开销很小,效率高
避免:绑定的资源,在回调之前就已经失效了
比如这里的this,[]里的资源,timer_.async_wait([this]{const auto&){this->print();});不能让
它在回调之前失效,比如让资源不失效?或者让正常析构的时候,把回调取消掉?先试试,在析构的
时候,调用timer_.cancel() 取消等待的回调,会出现的问题是:timer_在自身析构的过程中,也会
调用cancel的过程,而且如果回调函数中的参数有我自身,实际上已经没有任何意义了,在析构的时候调用已经晚了,所以cancel没有用
不太正确但是安全的方式:
进行一次判断
timer_async_wait([this](const auto& error) {
if(error == boost::asio::error::operation_aborted) {
std::cout << "cancel now\n";//出现问题,这个地方不能调用this等资源
} else {
this -> print();
}
});
|