std::make_shared特点

62 篇文章 0 订阅
33 篇文章 0 订阅

个人随笔 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
参考:https://stackoverflow.com/questions/20895648/difference-in-make-shared-and-normal-shared-ptr-in-c

std::make_shared是一个有意思的函数模板,它的使用,用于构造std::shared_ptr对象:

#include <memory>
// 下面两个都用来构建share_ptr对象
std::shared_ptr<Object> p1 = std::make_shared<Object>("foo");
std::shared_ptr<Object> p2(new Object("foo"));

但std::make_shared不同与std::shared_ptr的直接构造过程。
std::shared_ptr直接构造时,会涉及调用时传入的new Object(“foo”)对象,然后构造函数内部的new _Ref_count<_Ux>(_Px)存储计数,涉及两次堆内存分配。

template<class _Ty> 	class shared_ptr : public _Ptr_base<_Ty>
template<class _Ty> 	class _Ptr_base
	element_type * _Ptr{nullptr};
	_Ref_count_base * _Rep{nullptr};
  _Set_ptr_rep_and_enable_shared(_Px, new _Ref_count<_Ux>(_Px));

template<class _Ty> 	class _Ref_count public _Ref_count_base
	_Ty * _Ptr;
	  
class __declspec(novtable) _Ref_count_base
	_Atomic_counter_t _Uses;
	_Atomic_counter_t _Weaks;

std::make_shared构造时,把Object对象与_Ref_count_base计数放到了一个_Ref_count_obj类中,一次new _Ref_count_obj分配出来,只涉及一次堆内存分配;
接着把分配出的内容指针加上偏移放入到std::shared_ptr的_Ptr, _Rep指针上完成std::shared_ptr构造。

// 在_Ref_count_obj中同时存储object与计数项
class __declspec(novtable) _Ref_count_base
	_Atomic_counter_t _Uses;
	_Atomic_counter_t _Weaks;
template<class _Ty> 	class _Ref_count_obj public _Ref_count_base
	aligned_union_t<1, _Ty> _Storage;


// FUNCTION TEMPLATE make_shared
template<class _Ty, class... _Types>
_NODISCARD inline shared_ptr<_Ty> make_shared(_Types&&... _Args)
{// make a shared_ptr
    const auto _Rx = new _Ref_count_obj<_Ty>(_STD forward<_Types>(_Args)...);
    shared_ptr<_Ty> _Ret;
    _Ret._Set_ptr_rep_and_enable_shared(_Rx->_Getptr(), _Rx);
    return (_Ret);
}

// std::shared_ptr类的直接设值对象与计数的接口
void _Set_ptr_rep(element_type * _Other_ptr, _Ref_count_base * _Other_rep)
{// take new resource
    _Ptr = _Other_ptr;
    _Rep = _Other_rep;
}

从堆上内存分配的角度来看,std::make_shared的使用,对比直接使用std::shared_ptr构造,可以减少一次堆内存的申请;
同时,因为内存在一起,ref_count与object的释放也是在一起的,不能够单独释放;这个即算是好处—减少了误操作,便于理解;也算是弊端—如果想单独提前把Object转移给别的对象,就做不到了。

个人随笔 (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春夜喜雨

稀罕你的喜欢!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值