提升回显服务器示例并在 lambda 中捕获此和 shared_from_this()

Boost echo server example and capturing this and shared_from_this() in lambda

本文关键字:shared from this 服务器 lambda      更新时间:2023-10-16

在boost async-tcp-echo-server示例中,有一个服务器类在新连接上创建一个会话:

acceptor.async_accept(socket, [this](boost::system::error_code ec) {
    if (!ec)
        std::make_shared<session>(std::move(socket))->start();
    do_accept();
});

session::start()功能主体:

void start() { do_read(); }

session::do_read方法是一个私有成员函数:

void do_read()
{
    auto self(shared_from_this());
    socket.async_read_some(boost::asio::buffer(data, sizeof(data)),
        [this, self](boost::system::error_code ec, std::size_t length) {
            if (!ec)
                do_write(length);
    });
}

如果我错了,请纠正我。
会话类继承自std::enable_shared_from_this因此在调用shared_from_this()时已创建控制块,并且不会发生未定义的行为。在do_read函数中shared_from_this()函数用于允许在内存中仍然存在的对象上调用do_write()方法。如果不使用shared_from_this(),则可以在到达范围结束时删除该对象。

为什么在 lambda 表达式中捕获this
do_write()方法是在this上调用还是self

在 C++14 中,我可以替换:

auto self(shared_from_this());
socket.async_read_some(boost::asio::buffer(data, sizeof(data)),
    [this, self] ...

跟:

socket.async_read_some(boost::asio::buffer(data, sizeof(data)),
        [this, shared_from_this()] ...

?甚至这样:

socket.async_read_some(boost::asio::buffer(data, sizeof(data)),
    [self = shared_from_this()](boost::system::error_code ec, std::size_t length) {
        if (!ec)
            self->do_write(length);
});  

self对象作为所有权令牌捕获到 lambda 中:只要 lambda 存在,令牌就会存在,并且对象不会被销毁。

捕获this在这里是多余的,但没有它,人们将不得不编写

if (!ec)
    self->do_write(length);

而不是

if (!ec)
    do_write(length);

这与

if (!ec)
    this->do_write(length);

因此,捕获this主要是为了提高可读性。