实例化类对象时遭遇boost::asio::io_context已删除函数使用错误
问题成因与解决方案
这个问题我太熟了!核心原因是你在传递io_service(也就是Boost Asio后来重命名的io_context)时用了传值方式,而Asio的IO上下文对象从设计上就是不可拷贝的——它的拷贝构造函数被显式标记为删除状态,所以编译器直接抛出了use of deleted function的错误。
具体拆解错误来源
先看你的构造函数定义:
cnx::cnx(ioservice io) { this->s = new tcp::socket(io); }
这里的参数ioservice io是传值,当你执行cnx c(io);或new cnx(io);时,编译器会尝试把你定义的io对象拷贝一份传给构造函数。但io_context(ioservice是它的旧别名)作为管理整个IO事件循环的核心对象,拷贝会导致底层资源(如epoll/kqueue句柄)被重复管理,完全违背Asio的设计逻辑,因此Boost直接禁用了它的拷贝构造函数和赋值运算符(即= delete)。
快速修复方案
把构造函数的参数改成引用传递(或者指针,引用更符合C++的使用习惯),这样就不会触发拷贝操作,直接复用原对象的引用:
修改后的头文件
using boost::asio::ip::tcp; typedef boost::asio::io_service ioservice; class cnx { public: // 这里添加&改为引用传递 cnx(ioservice& io); private: tcp::socket *s; };
修改后的cpp文件
// 参数同步改为引用 cnx::cnx(ioservice& io) { this->s = new tcp::socket(io); }
现在再用你原来的方式实例化:
ioservice io; cnx c(io); // 正常运行 // 或者动态分配 cnx* c = new cnx(io); // 同样没问题
进阶安全建议(可选)
如果你的场景比较复杂(比如涉及异步操作、对象生命周期管理),可以用std::shared_ptr来托管ioservice,避免因引用对象提前销毁导致的问题:
// 头文件 #include <memory> class cnx { public: cnx(std::shared_ptr<ioservice> io); private: std::shared_ptr<ioservice> io_ptr; tcp::socket *s; }; // cpp文件 cnx::cnx(std::shared_ptr<ioservice> io) : io_ptr(io) { this->s = new tcp::socket(*io_ptr); } // 实例化 auto io = std::make_shared<ioservice>(); cnx c(io);
内容的提问来源于stack exchange,提问作者Fnr
相关产品推荐
相关产品推荐

