boost::shared_ptr智能指针分析

本文详细分析了boost::shared_ptr智能指针的使用,包括无参构造、带有删除器和自定义分配器的构造、从其他智能指针或weak_ptr复制等。还探讨了在标准容器中的应用以及如何定制删除器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 简介

   boost.smart_ptr 库中最有价值、最重要的组成部分,也是最有用的。
   shared_ptr 与 scoped_ptr 一样 包装了new 操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针,可以被自由地拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0)它时才删除被包装的动态分配的对象。shared_ptr 也可以 安全地放到标准容器中,并弥补了auto_ptr 因为转移语义而不能把指针作为STL容器元素的缺陷。

2. shared_ptr 分析

  通过shared_ptr 的源码我们可以看出,shared_ptr 要比同为智能指针的scoped_ptr 复杂许多。这里就列举出shared_ptr 的全部源码,我们只分析shared_ptr的重要部分。
  shared_ptr 与 scoped_ptr 同样是用于管理new动态分配对象的只能指针,因此功能上有很多相似之处:它们都重载了* 和 ->操作符以模拟原始指针的行为,提供隐式bool类型转换以判断指针的有效性,get() 可以得到原始指针,并且没有提供指针算术操作。
  但shared_ptr 的名字表明了它与 scoped_ptr 的主要不同:它是可以被安全共享的——shared_ptr 是一个“全功能”的类,有着正常的拷贝、赋值语义,也可以进行shared_ptr间的比较,是“最智能”的智能指针。
  shared_ptr 有多钟形式的构造函数,应用于各种可能的情形:
  • 无参的 shared_ptr()创建一个持有空指针的shared_ptr;
  • shared_ptr(Y * p)获得指向类型T的指针p的管理权,同时引用计数置为1;
  • shared_ptr(Y * p,D d)行为类似 shared_ptr(Y * p),但使用参数d指定了析构时的定制删除器,而不是简单的delete;
  • shared_ptr( Y * p, D d, A a )行为类似shared_ptr(Y * p,D d),但是使用了参数a指定了构造器,被用做分配空间,允许自定义自己的构造行为;
  • shared_ptr( shared_ptr const & r ) 从另外一个shared_ptr 获取指针的管理权,同时引用计数加1,结果是两个 shared_ptr 共享一个指针的管理权;
  • shared_ptr( weak_ptr<Y> const & r ) 从一个weak_ptr构造shared_ptr。这使得weak_ptr的使用具有线程安全性,因为指向weak_ptr参数的共享资源的引用计数将会自增(weak_ptr不影响共享资源的引用计数)。如果weak_ptr为空(r.use_count() == 0),shared_ptr 抛出一个类型为bad_weak_ptr的异常。
  • shared_ptr( std::auto_ptr<Y> & r ) 从一个auto_ptr 获得指针的管理权,同时引用计数置为1,同时auto_ptr 自动失去管理权;
  • operator=赋值操作符可以从另外一个shared_ptr 或auto_ptr获取指针的管理权,其行为同构造函数。
  下面是其对应的构造函数:
shared_ptr() BOOST_SP_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+
{
}

template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
{
	boost::detail::sp_pointer_construct( this, p, pn );
}

template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
{
	boost::detail::sp_deleter_construct( this, p );
}

template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
{
	boost::detail::sp_deleter_construct( this, p );
}

shared_ptr( shared_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
{
}

template<class Y>
explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
{
	boost::detail::sp_assert_convertible< Y, T >();

	// it is now safe to copy r.px, as pn(r.pn) did not throw
	px = r.px;
}

template<class Y>
explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn()
{
	boost::detail::sp_assert_convertible< Y, T >();
	
	Y * tmp = r.get();
	pn = boost::detail::shared_count( r );

	boost::detail::sp_deleter_construct( this, tmp );
}

shared_ptr & operator=( shared_ptr const & r ) BOOST_SP_NOEXCEPT
{
	this_type(r).swap(*this);
	return *this;
}
  shared_ptr 的reset()函数的行为与scoped_ptr也不尽相同,它的作用是将引用计数减1,停止对指针的共享,除非引用计数为0,否则不会发生删除操作。带参数的reset()则类似相同形式的构造函数,原指针引用计数减1的同时改为管理另一个指针。
  shared_ptr 有两个专门的函数来检查引用计数,unique()在shared_ptr是指针的唯一所有者时返回true(这是shared_ptr的行为类似auto_ptr或scoped_ptr),use_count()返回当前指针的引用计数。要小心,use_count()应该仅
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值