You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实例化类对象时遭遇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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:33:38