这篇Demo将叙两点。
1.调用bind,并搭配占位符placeholders::error将函数或成员函数适配为asio要求的handler。使用steady_timer,结合转换后的handler,实现回调函数的调用。
2.通过lambda表达式将函数或成员函数转换成符合asio要求的handler。使用steady_timer,结合转换后的handler,实现回调函数的调用。
#pragma once #define BOOST_ASIO_DISABLE_STD_CHRONO #include <boost/asio.hpp> #include <boost/chrono.hpp> #include <boost/system/error_code.hpp> #include <boost/asio/steady_timer.hpp> #include <boost/function.hpp> #include <boost/bind.hpp> using namespace boost::asio; class timer_with_func { typedef timer_with_func this_type; //定义自身别名,方便使用 private: int m_icount = 0; //计数器成员变量 int m_icount_max = 0; //计数器上限 boost::function<void()> m_f; //function对象,持有无参无返回的可调用物 steady_timer m_t; //asio定时器对象 public: template<typename F> //模板类型,可以接收任意可调用物 timer_with_func(io_service& io, int x, F func) : m_icount_max(x), //初始化计数器 m_f(func), //初始化回调函数 m_t(io) //启动计时器 { m_t.expires_from_now(boost::chrono::milliseconds(2000)); init(); //异步等待计时器,注册回调函数 } //bind表达式法:使用bind搭配占位符placeholders::error将函数或成员函数适配为asio要求的handler //private: // void init() // { // m_t.async_wait(bind( //使用bind绑定成员函数 // &this_type::handler, this, //传递this指针 // boost::asio::placeholders::error)); //使用error站位符传递错误码 // } // // void handler(const boost::system::error_code&) // { // if (m_icount++ >= m_icount_max) //如果计数器到达上限则退出 // { // return; // } // // m_f(); //调用function对象 // // m_t.expires_from_now(boost::chrono::milliseconds(2000)); //设置定时器的终止时间为2s之后 // // m_t.async_wait(bind( //再次启动定时器,异步等待 // &this_type::handler, this, // boost::asio::placeholders::error)); // } //lambda表达式法: private: typedef void(handler_type)(const boost::system::error_code&); //定义handler类型,一定要这样做 boost::function<handler_type> m_handler = //lambda的handler [&](const boost::system::error_code&) //捕获引用,包括this { if (m_icount++ >= m_icount_max) { return; } m_f(); m_t.expires_from_now(boost::chrono::milliseconds(2000)); //设置定时器终止时间 m_t.async_wait(m_handler); //再次异步等待 }; void init() { m_t.async_wait(m_handler); //异步等待,注册回调函数 } }; //timer_with_func定义结束
调用文件
#include <iostream> #define BOOST_ASIO_DISABLE_STD_CHRONO #include <boost/asio.hpp> #include <boost/chrono.hpp> #include <boost/system/error_code.hpp> #include <boost/asio/steady_timer.hpp> #include "time_with_func.h" using namespace boost::asio; int main() { io_service io; //steady_timer t1(io); //t1.expires_from_now(boost::chrono::milliseconds(5000)); //std::cout << t1.expires_at() << std::endl; //std::cout << t1.expires_from_now() << std::endl; ////t1.wait(); //t1.async_wait( // [](const boost::system::error_code& ec) { // std::cout << "hello asio." << std::endl; //}); timer_with_func t1(io, 5, [] {std::cout << "hello timer1." << std::endl; }); //启动第一个定时器 timer_with_func t2(io, 5, [] {std::cout << "hello timer2." << std::endl; }); //启动第二个定时器 io.run(); //io_service等待异步调用结束 std::cout << "Hello World!\n"; getchar(); }
问题:
定时器对象一旦创建,就会开始计时。如上,在对定时器进行初始化是分两步进行,io_service在成员列表里就赋给了定时器,而在构造函数内,还给定时器赋了一个终止时间。这样定时器是在哪一步开始计时?