全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

C++中的std::shared_from_this有什么用?C++安全获取this的shared_ptr【智能指针】

std::shared_from_this的作用是让已由std::shared_ptr管理的对象安全生成指向自身的另一个std::shared_ptr;必须公有继承std::enable_shared_from_this,且仅在对象已被shared_ptr拥有后(不可在构造函数中)调用,否则抛std::bad_weak_ptr。

std::shared_from_this 的作用是:让一个已由 std::shared_ptr 管理的对象,能安全地生成指向自身的另一个 std::shared_ptr,避免重复管理或悬空指针。

为什么不能直接用 new 构造 shared_ptr?

如果对象已经由某个 shared_ptr 管理(比如被外部创建并传入),你再用 newmake_shared 包装 this,会导致两个独立的控制块,引用计数互不感知——析构两次、内存崩溃、UB(未定义行为)。

正确做法是:对象必须继承自 std::enable_shared_from_this,然后调用 shared_from_this()

怎么安全使用 shared_from_this?

  • 类需公有继承 std::enable_shared_from_this
  • 只能在对象已被 shared_ptr 拥有时调用(即:该对象必须是通过 make_sharedshared_ptr 构造出来的)
  • 不能在构造函数里调用 —— 此时控制块还没完全建立,会抛 std::bad_weak_ptr
  • 推荐在成员函数中使用,比如回调注册、异步任务传递自身等场景

典型使用场景举例

比如一个网络连接类需要把自身传给异步读取回调:

class Connection : public std::enable_shared_from_this {
public:
    void start_read() {
        auto self = shared_from_this(); // 安全获取自身 shared_ptr
        socket_.async_read_some(buffer_, [self](auto ec, size_t n) {
            self->on_read(ec, n); // 即使 Connection 已被释放,self 也能保活
        });
    }
private:
    tcp::socket socket_;
    void on_read(std::error_code, size_t) { /* ... */ }
};

这样即使外层的 shared_ptr 提前释放,回调里的 self 仍能保证对象存活到回调执行完。

常见错误和注意事项

  • 忘记继承 enable_shared_from_this → 编译失败(shared_from_this 未定义)
  • 对象不是由 shared_ptr 创建(如栈对象或裸指针 new)→ 运行时抛 std::bad_weak_ptr
  • 想在构造函数中“提前保存自己” → 不行,控制块尚未就绪;可改用延迟初始化(如第一次调用时 lazy-init)
  • 多继承时注意模板参数要写对类型,别写成派生类名以外的别名

基本上就这些。shared_from_this 不复杂,但容易忽略前提条件,用对了才能真正安全。


#   # c++  # 异步任务  # 为什么  # red  # 成员函数  # 构造函数  # 指针  # 继承  # 公有继承  # 多继承  # 空指针  # 对象  # this  # 异步  # 回调  # 已被  # 已由  # 还没  # 是由  # 也能  # 两次  # 能在  # 可在  # 再用 


相关文章: 网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?  制作充值网站的软件,做人力招聘为什么要自己交端口钱?  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  网站按钮制作软件,如何实现网页中按钮的自动点击?  历史网站制作软件,华为如何找回被删除的网站?  制作网站建设的公司有哪些,网站建设比较好的公司都有哪些?  保定网站制作方案定制,保定招聘的渠道有哪些?找工作的人一般都去哪里看招聘信息?  高端云建站费用究竟需要多少预算?  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  c++ stringstream用法详解_c++字符串与数字转换利器  北京企业网站设计制作公司,北京铁路集团官方网站?  建站之星安装需要哪些步骤及注意事项?  上海网站制作开发公司,上海买房比较好的网站有哪些?  打鱼网站制作软件,波克捕鱼官方号怎么注册?  建站之星代理平台如何选择最佳方案?  如何快速搭建个人网站并优化SEO?  免费网站制作appp,免费制作app哪个平台好?  如何通过虚拟主机快速搭建个人网站?  如何在七牛云存储上搭建网站并设置自定义域名?  教育培训网站制作流程,请问edu教育网站的域名怎么申请?  html制作网站的步骤有哪些,iapp如何添加网页?  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  如何在Windows服务器上快速搭建网站?  如何用搬瓦工VPS快速搭建个人网站?  建站之星后台管理如何实现高效配置?  电商网站制作价格怎么算,网上拍卖流程以及规则?  jQuery 常见小例汇总  如何零基础在云服务器搭建WordPress站点?  建站主机核心功能解析:服务器选择与网站搭建流程指南  如何通过智能用户系统一键生成高效建站方案?  制作销售网站教学视频,销售网站有哪些?  最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?  合肥做个网站多少钱,合肥本地有没有比较靠谱的交友平台?  如何在Windows 2008云服务器安全搭建网站?  开封网站制作公司,网络用语开封是什么意思?  c# 服务器GC和工作站GC的区别和设置  长沙企业网站制作哪家好,长沙水业集团官方网站?  nginx修改上传文件大小限制的方法  微信小程序 五星评分(包括半颗星评分)实例代码  大连网站设计制作招聘信息,大连投诉网站有哪些?  制作旅游网站html,怎样注册旅游网站?  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  建站之星IIS配置教程:代码生成技巧与站点搭建指南  c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗  桂林网站制作公司有哪些,桂林马拉松怎么报名?  网站制作公司,橙子建站是合法的吗?  如何在Golang中使用encoding/gob序列化对象_存储和传输数据  javascript中的try catch异常捕获机制用法分析  建站之星安装模板失败:服务器环境不兼容?  利用JavaScript实现拖拽改变元素大小 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。