In boost async-tcp-echo-server example there is a server class which creates a session on a new connection:
acceptor.async_accept(socket, [this](boost::system::error_code ec) {
if (!ec)
std::make_shared<session>(std::move(socket))->start();
do_accept();
});
session::start()
function body:
void start() { do_read(); }
session::do_read
method is a private member function:
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);
});
}
Please, correct me if I am wrong.
The session class inherits from std::enable_shared_from_this
so a control block is already created when calling shared_from_this()
and no undefined behavior will occur. In the do_read
function shared_from_this()
function is used to allow do_write()
method to be called on object which still exists in memory. If shared_from_this()
wouldn't be used the object could be deleted when reaching end of scope.
Why is this
captured in lambda expression?
Is do_write()
method called on this
or self
?
In C++14 could I replace:
auto self(shared_from_this());
socket.async_read_some(boost::asio::buffer(data, sizeof(data)),
[this, self] ...
with:
socket.async_read_some(boost::asio::buffer(data, sizeof(data)),
[this, shared_from_this()] ...
? Or even with that:
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);
});
?