Asio:示例中使用自共享指针

Hyd*_*ydn 3 c++ boost shared-ptr boost-asio

看一下Asio库的例子,例如这个例子(例如,第37行),我看到有时候他们会创建一个共享指针(他们自己命名),并在lambda中捕获它们,在那里他们称之为asio功能,但我不明白它的目的是什么.我甚至没看到它用过.

那么,为什么他们这样做呢?


相关守则:

..在服务器类中......(创建会话的地方)

if (!ec)
{
    std::make_shared<session>(std::move(socket_))->start();
}
Run Code Online (Sandbox Code Playgroud)

... session::start()会员方法:

void start()
  {
    do_read();
  }
Run Code Online (Sandbox Code Playgroud)

... session::do_read()成员方法(我感兴趣的地方):

void do_read()
  {
    auto self(shared_from_this());                    // <<< ---WHY THIS??????
    socket_.async_read_some(asio::buffer(data_, max_length),
        [this, self](std::error_code ec, std::size_t length)
        {
          if (!ec)
          {
            do_write(length);
          }
        });
  }
Run Code Online (Sandbox Code Playgroud)

Whi*_*TiM 6

目的std::enable_shared_from_this<>std::shared_ptrstd::shared_ptr拥有对象调用shared_from_this成员函数的句柄创建额外的.


if (!ec)
{
     std::make_shared<session>(std::move(socket_))->start();
}
Run Code Online (Sandbox Code Playgroud)

以上- ^^^ -是创建一条线的地方session.正如你所看到的std::shared_ptr,返回的那个std::make_shared将被销毁;,这也应该破坏session创建的...

但因为start()方法调用do_read()被定义为......

void do_read()
  {
    auto self(shared_from_this());
    socket_.async_read_some(asio::buffer(data_, max_length),
        [this, self](std::error_code ec, std::size_t length)
        {
          if (!ec)
          {
            do_write(length);
          }
        });
  }
Run Code Online (Sandbox Code Playgroud)

self增加了shared_ptr引用计数.因此,创建的原始文件shared_ptr的破坏不会破坏对象,而是将self作为对创建对象的引用.


还要知道Lambda可以比它的调用者更长... boost::asio::async_write是一个异步方法,在复制它的参数后立即返回.你到达之前通过lambda不能执行寿命终结你的session.因此,如果没有std::shared_ptr创建的附加shared_from_this,析构函数将运行.这个附加功能shared_ptr可以防止析构函数session运行,直到调用lambda函数并且它的参数被破坏.