提升回显服务器示例并在 lambda 中捕获此和 shared_from_this()
Boost echo server example and capturing this and shared_from_this() in lambda
在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
主要是为了提高可读性。
相关文章:
- 如何解决"invalid conversion from 'char' to 'const char*'"
- std::async from std::async in windows xp
- 引用 std::shared:ptr 以避免引用计数
- std::is_reference from std::any
- std::time_point from and to std::string
- "No suitable conversion function from 'std::string' to 'const char *' exists"
- std::chrono::time_point from std::string
- Visual accept std::string from std::byte iterator
- C++中链表的错误"Abort signal from abort(3) (sigabrt) "
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- C++ 中的"template <typename From, typename Tag> struct Alias;"是什么?
- from std::vector to adept::avector
- qt get child (Callout) from QChart
- Webassembly from Javascript
- Generate boost::uuids::uuid from boost::compute::detail::sha
- 无法使用 libtool 将 -shared 参数传递给 g++
- 什么是"Reading unbounded stream from standard input (Memory Management)"的例子
- Calling C++ dll from python
- 为什么我会收到"invalid conversion from 'Queue*/Stack*' to 'int'"错误消息?
- std::chrono 在从 main 或 from 类方法使用时给出不同的值