一、smart_ptr库概述
计算机系统中资源分很多种,内存是我们最常用的,内存使用需要申请和及时的释放。
1、RALL机制概述
为了管理内存等资源,C++程序员通常采用RALL(资源获取及初始化)机制,在类中构造函数中申请内存,在析构函数中释放内存。当对象是在栈上创建的,那么RALL机制会正常工作,离开作用域的时候会自动释放资源。如果使用new操作符进行创建,析构函数不能释放资源,需要使用delete关键字进行内存释放操作,如果未执行delete操作,那么这块内存资源就永远的失去了。
2、智能指针
智能指针实现了设计模式中的代理模式,代理原始指针的“裸”指针行为,为他添加了很多的特性。C++引入异常机制后,智能指针由一项技巧升级为一种非常重要的技术,如果没有智能指针,程序员需要new对象的正确时机,正确时机delete,到处编写异常捕获代码用来释放资源。boost库中的的smart_ptr库中的指针为下列6种:
主要介绍的是左边部分的4种智能指针,智能指针都位于命名空间boost中,需要包含头文件smart_ptr.hpp的头文件,即#include<boost\smart_ptr.hpp>
二、scoped_ptr:在析构函数中调用delete释放内存
首先我们定位到boost库中scoped_ptr,此智能指针在文件smart_ptr.hpp中,下面来解析此类的实现:
smart_ptr.hpp中的内容如下,所以我们需要进一步查看scoped_ptr.hpp的文件内从
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
scoped_ptr.hpp的内容如下:
#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
#define BOOST_SCOPED_PTR_HPP_INCLUDED
#include <boost/smart_ptr/scoped_ptr.hpp>
#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
需要查看boost/smart_ptr下的scoped_ptr.hpp的内容如下<内容有删减>:
#ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
#include <boost/smart_ptr/detail/sp_noexcept.hpp>
#include <boost/detail/workaround.hpp>
#ifndef BOOST_NO_AUTO_PTR
# include <memory> // for std::auto_ptr
#endif
namespace boost
{
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 ) BOOST_SP_NOEXCEPT : px( p )
{
}
explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_SP_NOEXCEPT : px( p.release() )
{
}
~scoped_ptr() BOOST_SP_NOEXCEPT
{
boost::checked_delete( px );
}
void reset(T * p = 0) BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
this_type(p).swap(*this);
}
T & operator*() const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
return *px;
}
T * operator->() const BOOST_SP_NOEXCEPT_WITH_ASSERT
{
BOOST_ASSERT( px != 0 );
return px;
}
T * get() const BOOST_SP_NOEXCEPT
{
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
void swap(scoped_ptr & b) BOOST_SP_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_SP_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() == 0;
}
template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_SP_NOEXCEPT
{
return p.get() != 0;
}
#endif
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_SP_NOEXCEPT
{
a.swap(b);
}
// get_pointer(p) is a generic way to say p.get()
template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_SP_NOEXCEPT
{
return p.get();
}
} // namespace boost
#endif // #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
定义了各种函数:
<1>scoped_ptr(scoped_ptr const &);
<2>scoped_ptr & operator=(scoped_ptr const &);
将<1>、<2>的声明为私有函数,就将赋值运算符和拷贝构造函数声明为私有,这样就是不能使用拷贝构造和赋值运算符。
<3>explicit scoped_ptr( T * p = 0 ) BOOST_SP_NOEXCEPT : px( p )
构造函数,初始化列表。
<4> ~scoped_ptr() BOOST_SP_NOEXCEPT
析构函数,用来释放私有变量T* px
<5> T & operator*() const BOOST_SP_NOEXCEPT_WITH_ASSERT
运算符重载,return *px
<6> T * operator->() const BOOST_SP_NOEXCEPT_WITH_ASSERT
运算符重载,return px
<7>T * get() const BOOST_SP_NOEXCEPT
返回指针px,return px;
<8> void swap(scoped_ptr & b) BOOST_SP_NOEXCEPT
交换当前的智能指针
<9>template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
<10>template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_SP_NOEXCEPT
运算符重载==,判断智能指针是否为空
<11>template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT
<12>template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_SP_NOEXCEPT
运算符重载!=,判断智能指针是否为空
<13>template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_SP_NOEXCEPT
交换智能指针
<14>template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_SP_NOEXCEPT
返回指针px,return p.px
三、shared_ptr,在boost库中smart_ptr库中的shared_ptr.hpp含有1000多行代码,认真解析其中的代码会获益良多