简介
scoped_ptr作为智能指针模板类首先用于确保动态分配的对象能够被正常的删除。其次scoped_ptr具有不能转让所持对象指针的所有权的特性。
使用scoped_ptr的优点在于:
- 使代码变得清晰简单,简单意味着更少的错误
- 没有增加多余的操作,安全的同时保证效率
socped_ptr位于boost/scoped_ptr.hpp
其实内部引用的是boost/smart_ptr/scoped_ptr.hpp
用法
#include <iostream>
#include <boost/scoped_ptr.hpp>
using namespace std;
using namespace boost;
class TEST{
public:
TEST(int value):value_(value){cout<<"TEST"<<endl;}
~TEST(){cout<<"~TEST"<<endl;}
int get_value(){return value_;}
private:
int value_;
};
int main()
{
{
scoped_ptr<TEST> ptr(new TEST(22));
if( ptr != nullptr)
{
//访问同指针类似
cout<<ptr->get_value()<<endl;
}
//在此处自动析构
}
cout<<"main end"<<endl;
}
输出如下所示:
TEST
22
~TEST
main end
源码分析
template<class T> class scoped_ptr // noncopyable
{
private:
T * px;
//拷贝构造函数,复制函数私有化,防止复制
scoped_ptr(scoped_ptr const &);
scoped_ptr & operator=(scoped_ptr const &);
typedef scoped_ptr<T> this_type;
//禁止同类对象进行一致性比较
void operator==( scoped_ptr const& ) const;
void operator!=( scoped_ptr const& ) const;
public:
typedef T element_type;
//显式构造函数
explicit scoped_ptr( T * p = 0 ): px( p ) // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px );
#endif
}
#ifndef BOOST_NO_AUTO_PTR
explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_constructor_hook( px );
#endif
}
#endif
//析构函数
~scoped_ptr() // never throws
{
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
boost::sp_scalar_destructor_hook( px );
#endif
boost::checked_delete( px );
}
//重置指针,
void reset(T * p = 0) // never throws
{
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type(p).swap(*this);
}
//*操作符重载
T & operator*() const // never throws
{
BOOST_ASSERT( px != 0 );
return *px;
}
//->操作符重载
T * operator->() const // never throws
{
BOOST_ASSERT( px != 0 );
return px;
}
//get返回对象指针,返回的指针不能作delete操作,不然会发生未定义行为
T * get() const BOOST_NOEXCEPT
{
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
//用于交换两个scoped_ptr保存的指针
void swap(scoped_ptr & b) BOOST_NOEXCEPT
{
T * tmp = b.px;
b.px = px;
px = tmp;
}
};
#if !defined( BOOST_NO_CXX11_NULLPTR )
//与空指针进行比较
template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
{
return p.get() != 0;
}
#endif
//交换函数
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
{
a.swap(b);
}
//get_pointer方法,类似get()方法。
template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
{
return p.get();
}