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

《C++ Primer第五版shared_ptr赋值与指针转换问题咨询》

关于std::shared_ptr的两个疑问解答

疑问1:赋值后sp1和sp2的use_count为何相同?

首先得明确书中描述的变量对应关系,你测试代码里的赋值操作是sp2 = sp1,这对应《C++ Primer》里的p = q——这里的p是被赋值的sp2,q是赋值来源sp1,可别搞反了!

《C++ Primer第五版》第12章描述:“p和q是持有可相互转换指针的shared_ptr。递减p的引用计数,递增q的计数;若p的计数变为0则释放其内存。”

结合你的代码一步步拆解:

  • 赋值前:sp1的use_count是1(独占一个int对象),sp2的use_count是0(指向nullptr,无关联对象)
  • 执行sp2 = sp1时:
    1. 首先递减p(sp2)的引用计数——但sp2原本计数就是0,所以这一步没有实际影响,也不会触发内存释放
    2. 让sp2共享q(sp1)的对象,因此递增q的引用计数(sp1的use_count从1变为2)
  • 为什么sp2的use_count也是2?因为shared_ptr的use_count是读取共享控制块里的数值。当sp2和sp1指向同一个对象时,它们共用同一个控制块,所以两者的use_count必然相等——你读取的是同一个计数器,结果自然一致。

书中的描述完全正确,只是你搞反了p和q对应的变量,才产生了理解偏差。

疑问2:为什么shared_ptr<int>不能赋值给shared_ptr<short>?

这里的核心是搞清楚“可相互转换指针”的含义:它指的是指针类型之间的隐式转换,而非数值类型的转换。

  • 举个合法的例子:如果有基类Base和派生类Derived,Derived*可以隐式转换为Base*,那么shared_ptr<Derived>就能赋值给shared_ptr<Base>,这完全符合书中“可相互转换指针”的场景。
  • 但int*和short*之间没有隐式转换关系:虽然short数值可以转成int,但指针是指向特定大小内存的类型——int通常指向4字节内存,short指向2字节内存,编译器不允许它们隐式转换,因此shared_ptr<int>和shared_ptr<short>之间也不能直接赋值。

至于容器要求类型完全一致,这是C++容器的强类型特性决定的。比如vector<shared_ptr<int>>只能存储shared_ptr<int>,哪怕shared_ptr<short>看起来类似也不行——容器的元素类型是严格匹配的,这和shared_ptr的指针转换规则是两个独立的概念。如果一定要转换,你可以用static_pointer_cast显式转换,但这通常不安全,因为int和short的内存大小不同,可能导致未定义行为。


内容的提问来源于stack exchange,提问作者Itachi Uchiwa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:23:41