当前位置: 首页 > news >正文

std::shared_ptr的别名构造函数

先看代码:

#include <iostream> #include <memory> struct Bar { int i{123}; }; struct Foo { Bar bar; }; int main(void) { std::shared_ptr<Bar> b; { auto f = std::make_shared<Foo>(); b = std::shared_ptr<Bar>(f, &(f->bar)); } std::cout << b->i << std::endl; return 0; }

运行这段代码会怎样?

答案是:正确运行输出 123 。

接下来我们分析下:

代码核心逻辑

std::shared_ptr<Bar> b; { auto f = std::make_shared<Foo>(); b = std::shared_ptr<Bar>(f, &(f->bar)); // 别名构造 } std::cout << b->i << std::endl; // 输出 123

关键点:shared_ptr别名构造函数(Aliasing Constructor)

template< class Y > shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept;

这个构造函数有两个相互独立的语义:

维度说明

所有权 (control block)

r共享,引用计数 +1,沿用r的 deleter

存储指针 (stored pointer)

是用户传入的ptr,可以指向任意位置(通常是被管理对象的成员或其向下转型)

也就是说:"管理什么" 和 "指向什么" 是解耦的。

执行时序分析

步骤Foo 引用计数关键事件

auto f = std::make_shared<Foo>()

1

在堆上构造 Foo(含bar.i = 123

b = shared_ptr<Bar>(f, &(f->bar))

2

bf共享 control block;b内部指针 =&f->bar

}内部块结束,f析构

1

Foo 不销毁(b仍持有共享所有权)

b->i

1

通过&f->bar访问i—— Foo 仍存活,安全

main返回,b析构

0

调用原始 Foo 的 deleter,正确销毁整个 Foo(不是只销毁 Bar)

总结要点

  1. Aliasing constructor 的本质:让一个shared_ptr"搭便车"延长另一个对象的生命周期,同时对外暴露不同的指针视图。
  2. deleter 永远来自原始 control block:即使最后释放的是 aliasingshared_ptr,它也调用原始对象的 deleter,不会用 aliasing 指针去delete。这就避免了对成员指针delete导致的 UB。
  3. get()返回的是 stored pointer:题目解释中"calling get() on this shared_ptr will always return a copy of ptr"指的就是这个语义——返回&f->bar,而不是原始的 Foo 指针。
  4. 典型用法:
    • 指向成员(本题场景)
    • 向下转型/侧向转型后保留所有权
    • shared_ptr<Derived>shared_ptr<Base>共享 control block
  5. 使用约束:程序员需保证 stored pointer 在该shared_ptr生命周期内一直有效(本例中由"成员位于被管理对象内部"自然保证)。
http://www.jsqmd.com/news/712177/

相关文章:

  • PLCopen规范C语言移植项目交付倒计时!——紧急上线前必须验证的7项合规性测试(含TUV认证预检Checklist)
  • RTL设计和HLS高层次设计
  • C++实现计算器功能
  • LACIN网络架构:完全互连网络的创新实现与优化
  • X平台算法解析:掌握黄金法则提升内容触及率与互动率
  • SAP ABAP实战:用BAPI ME_INFORECORD_MAINTAIN批量维护采购信息记录(含价格等级完整代码)
  • 收藏!全国首所网安本科高校2026招生!小白_程序员入行必看
  • 2026年水玻璃厂家专业度判定指南:水玻璃厂家哪家口碑好/水玻璃厂家哪家大/水玻璃厂家哪家实力大/水玻璃厂家哪家实力强/选择指南 - 优质品牌商家
  • Kafka集群管理新选择:深度体验Kafka-UI,对比CMAK/Offset Explorer谁更香?
  • DynamicVerse框架:4D动态场景重建与语义理解技术解析
  • 生产系统里维护 SAP Gateway System Alias 的正确打开方式
  • Flux Tasks API 的集成与使用指南
  • 参数传递规则问题-类型匹配
  • Smol轻量级模型:高效神经网络架构设计与应用
  • bool值不等于0都是true
  • 链表中倒数第k个结点-C++
  • 别再为CWRU轴承数据发愁了!一个Python函数搞定数据读取与划分(附完整代码)
  • ARM GICv3虚拟中断控制器与ICV_HPPIR1_EL1寄存器详解
  • 多项式优化框架设计与Julia实现实践
  • 解锁macOS视频预览新境界:QuickLookVideo全面解析与实战指南
  • Leetcode刷题总结-3.二叉树篇
  • 实战:在华为Atlas 300i Pro上部署YOLOv5模型进行目标检测(MindSpore+CANN)
  • 终极Django REST Framework数据分析指南:API使用统计与业务洞察实战
  • RPG Maker Decrypter技术深度解析:三版本加密算法实现与架构设计
  • 视觉因果发现:ToCT方法与CauSight模型解析
  • GAN判别器增强技术与对抗训练优化策略
  • Arm Cortex-X925错误记录寄存器架构与RAS技术解析
  • Shark007 Advanced Codecs
  • 安吉办公椅生产厂家有哪些?2026办公网椅生产厂/人体工学椅/安吉办公椅源头工厂调研-商用座椅领军好物精选 - 栗子测评
  • mousemaster:用键盘驱动鼠标,提升效率与缓解RSI的终极方案