Timer.4 使用成员函数作为 Completion Handler

Timer.4——使用成员函数作为 completion handler #


原文链接 | 源码链接

在本教程中,我们将了解如何使用类成员函数作为 completion handler。该程序的执行方式应与 教程 Timer.3 中的程序相同。

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>

现在,我们不再像前面教程中那样将自由函数(free function) print 定义为 completion handler,而是定义一个名为 printer 的类。

class printer
{
public:

这个类的构造函数接收一个 io_context 的引用对象,并在初始化成员变量 timer_ 时使用它。用于结束程序运行的计数器 counter 现在也是该类的成员。

  printer(boost::asio::io_context& io)
    : timer_(io, boost::asio::chrono::seconds(1)),
      count_(0)
  {

boost::bind()函数可以用来处理自由函数,也可以用来绑定类的成员函数。由于所有非静态类成员函数都有一个隐式的 this 参数,我们需要将 this 绑定到该函数。与 教程 Timer.3 中一样,boost::bind() 将我们的 completion handler (现在是成员函数)转换为可以调用的函数对象,就好像它的签名和 void(const boost::system::error_code&) 一样。

请注意,这里没有指定 boost::asio::placeholders::error 占位符,因为 print 成员函数不接收 error 对象作为参数。

    timer_.async_wait(boost::bind(&printer::print, this));
  }

在类的析构函数中,我们打印出计数器的最终值。

  ~printer()
  {
    std::cout << "Final count is " << count_ << std::endl;
  }

print 成员函数与 教程 Timer.3 中的自由函数 print 非常相似,不同之处在于它现在对类的数据成员进行操作,而不是将 timer 和计数器作为参数传入。

  void print()
  {
    if (count_ < 5)
    {
      std::cout << count_ << std::endl;
      ++count_;

      timer_.expires_at(timer_.expiry() + boost::asio::chrono::seconds(1));
      timer_.async_wait(boost::bind(&printer::print, this));
    }
  }

private:
  boost::asio::steady_timer timer_;
  int count_;
};

main 函数比之前简单得多,它在运行 io_context 之前会声明一个局部 printer 对象。

int main()
{
  boost::asio::io_context io;
  printer p(io);
  io.run();

  return 0;
}