gpt4 book ai didi

c++ - 在包含处理程序的类被破坏后,Asio 调用处理程序

转载 作者:行者123 更新时间:2023-11-30 05:45:50 25 4
gpt4 key购买 nike

我有一个 X 类,它引用了 boost::asio::io_service 和一个连接的 boost::astio::ip::tcp::socket在它的构造函数中。该类处理网络数据的发送和接收。

我遇到的一个问题是主代码要求 X 发送一条消息 X::sendMessage(),然后主代码在下一行删除了 X。因此,X 调用 boost::asio::async_write,使用 lambda 作为处理程序,然后 X 被删除,调用其析构函数,关闭套接字。没有X了。但是过了一会儿 boost::asio::io_service 调用了我在 boost::asio::async_write 调用中使用的 lambda 处理程序,它现在在一个被破坏的类中, boost::system::error_code 设置为“成功”。

有什么方法可以告诉 lambda 该类已被破坏并且它不应该与类的成员和方法混淆?

也许我可以以某种方式取消在 ~X() 中调用 lambda 处理程序?尽管写入操作可能已经完成并安排了由 boost::asio::io_service 执行的处理程序,所以实际上没有什么可以取消的。

请注意,我无法对 boost::asio::io_service 对象执行任何操作,因为它由主代码传递给 X,并且它处理的不仅仅是网络。

class X
{
public:
X(boost::asio::io_service &io, boost::asio::ip::tcp::socket socket)
: io(io), socket(std::move(socket)){ }

~X()
{
if (socket.is_open()) {
socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
socket.close();
}
}

void X::sendMessage()
{
boost::asio::async_write(socket, boost::asio::buffer(m.data, m.size),
[this](boost::system::error_code ec, std::size_t /*length*/)
{
std::cout << ec.message() << std::endl; // Success!
// `this' is invalid though

if (!ec) {
// code
} else {
// code
}
});
}

private:
boost::asio::io_service &io;
boost::asio::ip::tcp::socket socket;

编辑:

现在我只是创建了一个带有 bool 的共享指针,我将其传递给 lambdas 并在析构函数中将其设置为 true,以便 lambdas 可以判断对象是否已经被破坏。这是一个肮脏的黑客,但它现在有效。不过从长远来看,我希望有一个更优雅的解决方案。

最佳答案

如果您想确保您的对象在 asio 框架引用它时保持事件状态,请将指向该对象的共享所有权智能指针传递到 lambda 表达式中。例如:

class X : public enable_shared_from_this<X>
// ...

boost::shared_ptr<X> that = this->shared_from_this();
boost::asio::async_write(socket, boost::asio::buffer(m.data, m.size),
[that](boost::system::error_code ec, std::size_t /*length*/)

关于c++ - 在包含处理程序的类被破坏后,Asio 调用处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29202280/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com