【发布时间】:2015-05-25 23:20:36
【问题描述】:
我有一个类 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 可以判断对象是否已经被破坏。这是一个肮脏的黑客,但它现在有效。不过,从长远来看,我希望有一个更优雅的解决方案。
【问题讨论】:
标签: c++ c++11 boost lambda boost-asio