网站首页 文章专栏 请教shared_ptr在析构时的奇怪表现。
请教shared_ptr在析构时的奇怪表现。
编辑时间:2019-12-25 15:38:23 作者:lijixiang2010 4条评论


    出自:purecpp.cn

    地址: www.purecpp.cn

    转载请注明出处!


来说两句吧
登录才能发表评论。
最新评论
  • qicosmos
    qicosmos 2019-12-26 14:39:23

    Hi lijixiang,

    你这个问题问得很好。

    原因是这样的:shared_ptr的构造函数是一个模板函数,shared_ptr会记住这个指针类型即你例子中的Base*类型,shared_ptr析构的时候会调用delete Base*的指针,而不管这个Base是否有虚的析构函数。

    简言之,在share_ptr模板类型和实际类型的析构函数都会被调用到。而unique_ptr则不会去调用模板类型的析构函数。


    也许你还想进一步了解为什么unique_ptr不会去调用基类的析构函数,这是因为shared_ptr和unique_ptr的实现方式不同导致的,shared_ptr中的模板参数T允许是一个incomplete type,最终是需要一个完整类型的,通过在最后删除的时候去调用这个incomplete type的析构函数来保证类型的完整性;

    而unique_ptr一开始就要求这个模板类型必须是complete type,所以也就不需要去调用模板参数类型的析构函数了。

  • qicosmos
    hl4 2019-12-29 17:45:30

    我的理解如下,

    多个对象使用shared_ptr不能确定谁是最后一个指针,它在声明指针时更不可能知道指针指向的实际类型,所以这里调用实际类型的析构就是shared_ptr必须解决的问题。

    unique_ptr则相反,它拥有指针(一般是它自己创建,少部分调用创建代码,总之是知道如何创建这个指针)它声明时就知道这个指针一定是它释放(或者交给知道如何释放代码),所以声明时知道实际类型。

    场景上决定,unique_ptr不需要解决shared_ptr的问题。

  • qicosmos
    antiwalker 2022-05-17 08:08:48

    std::shared_ptr<Base> p = std::make_shared<Inherit>();

    这句,实际是make_shared创建了一个std::shared_ptr<Inherit>类型的对象,然后copy构造或者copy assignment给外面的p,从而p对象内hold的raw pointer是Inherit类型。所以不知道该是特性还是巧合,应该不是bug。

  • qicosmos
    向日葵骑士 2022-12-15 07:45:01

    我个人认为这中uniqueptr和sharedptr的奇怪不同是因为标准库的设计目的。

    uniqueptr 的性能应该媲美原始指针,因此有很多的事情需要在编译期确定。 

    sharedptr 因为有引用计数等实现方法,性能上完全不能媲美原始指针。那倒不如将sharedptr中的大量功能设计成不依赖编译期完全确定。可能你会觉得“sharedptr这样设计不就性能更低了吗?” 但 sharedptr就是用起来无脑简单的。

    设计目的的不同 ,让两种共享指针上 做析构这件事时 有了些许差异。 





Absolutely

purecpp

一个很酷的modern c++开源社区


[社区开源项目列表,点击前往]


purecpp社区自2015年创办以来,以“Newer is Better”为理念,相信新技术可以改变世界,一直致力于现代C++研究、应用和技术创新,期望通过现代C++的技术创新来提高企业生产力和效率。


社区坚持只发表原创技术文章,已经累计发表了一千多篇原创C++技术文章;


组织了十几场的C++沙龙和C++大会,有力地促进了国内外C++开发者之间的技术交流;


开源了十几个现代C++项目,被近百家公司所使用,有力地推动了现代C++在企业中的应用。


期待更多的C++爱好者能参与到社区C++社区的建设中来,一起为现代C++开源项目添砖加瓦,一起完善C++基础设施和生态圈。


微信公众号:purecpp, 社区邮箱: purecpp@163.com


友情链接