|

楼主 |
发表于 2017-7-10 11:28:43
|
显示全部楼层
怎么绑定成员函数(之前绑定的是自由函数):
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();
- }
- });
复制代码 |
|