概述
从名字可以看得出来,与scoped_ptr不同的是,这是一个管理堆内存的指针,scoped_array 类模板存储一个指向一个动态分配数组的指针(动态分配数组是用 C++new[] 表达式分配的)。它提供了一个基本的“资源获取就是初始化”的机制,不包括共享所有权或所有权转让语义。无论它的名字还是语义上的强制要求(noncopyable),它的唯一目的就是在当前作用域内独自保留所有权。因为它是noncopyable ,对于不可拷贝的指针来说,它比shared_array 更加安全。因为 scoped_array 很简单,在它的通常实现中,每一个操作都和内建数组指针有同样的速度,而且的它所占用的空间并不比内建数组指针多。
源代码如下:
#ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
#define BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
//
// shared_array.hpp
//
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/smart_ptr/shared_array.htm for documentation.
//
#include <boost/config.hpp> // for broken compiler workarounds
#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#include <boost/smart_ptr/detail/shared_array_nmt.hpp>
#else
#include <memory> // TR1 cyclic inclusion fix
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/detail/workaround.hpp>
#include <cstddef> // for std::ptrdiff_t
#include <algorithm> // for std::swap
#include <functional> // for std::less
namespace boost
{
//
// shared_array
//
// shared_array extends shared_ptr to arrays.
// The array pointed to is deleted when the last shared_array pointing to it
// is destroyed or reset.
//
template<class T> class shared_array
{
private:
// Borland 5.5.1 specific workarounds
typedef checked_array_deleter<T> deleter;
typedef shared_array<T> this_type;
public:
typedef T element_type;
explicit shared_array(T * p = 0): px(p), pn(p, deleter())
{
}
//
// Requirements: D's copy constructor must not throw
//
// shared_array will release p by calling d(p)
//
template<class D> shared_array(T * p, D d): px(p), pn(p, d)
{
}
// generated copy constructor, destructor are fine...
#if defined( BOOST_HAS_RVALUE_REFS )
// ... except in C++0x, move disables the implicit copy
shared_array( shared_array const & r ): px( r.px ), pn( r.pn ) // never throws
{
}
#endif
// assignment
shared_array & operator=( shared_array const & r ) // never throws重载=
{
this_type( r ).swap( *this );
return *this;
}
void reset(T * p = 0)//指针管理权转移
{
BOOST_ASSERT(p == 0 || p != px);
this_type(p).swap(*this);
}
template <class D> void reset(T * p, D d)//与上面不同的是,这个可以自己制定指针管理权转移时的操作,可以定制自己的析构函数
{
this_type(p, d).swap(*this);
}
T & operator[] (std::ptrdiff_t i) const // never throws 重载[],可以直接使用数组下表
{
BOOST_ASSERT(px != 0);
BOOST_ASSERT(i >= 0);
return px[i];
}
T * get() const // never throws
{
return px;
}
// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>
bool unique() const // never throws 检查scoped_array是不是对指针的唯一管理权
{
return pn.unique();
}
long use_count() const // never throws
{
return pn.use_count();
}
void swap(shared_array<T> & other) // never throws交换指针
{
std::swap(px, other.px);
pn.swap(other.pn);
}
void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
{
return pn.get_deleter( ti );
}
private:
T * px; // contained pointer
detail::shared_count pn; // reference counter
}; // shared_array
template<class T> inline bool operator==(shared_array<T> const & a, shared_array<T> const & b) // never throws
{
return a.get() == b.get();
}
template<class T> inline bool operator!=(shared_array<T> const & a, shared_array<T> const & b) // never throws
{
return a.get() != b.get();
}
template<class T> inline bool operator<(shared_array<T> const & a, shared_array<T> const & b) // never throws
{
return std::less<T*>()(a.get(), b.get());
}
template<class T> void swap(shared_array<T> & a, shared_array<T> & b) // never throws
{
a.swap(b);
}
template< class D, class T > D * get_deleter( shared_array<T> const & p )
{
return static_cast< D * >( p._internal_get_deleter( BOOST_SP_TYPEID(D) ) );
}
} // namespace boost
#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#endif // #ifndef BOOST_SMART_PTR_SHARED_ARRAY_HPP_INCLUDED
与scoped_ptr不同的是,它没有重载*,->因为它不是一个普通的指针,释放内存使用delete[]而不是delete,因为不是容器,所以也不能提供容器的迭代器操作。使用范例如下:
#include <boostsmart_ptr.hpp>
#include <string>
using namespace std;
using namespace boost;
int main()
{
scoped_array<int> a(new int[10]);
fill_n(&a[0],10,3);
a[9] = a[1] + a[2] + a[3];//9
cout<<a[1]<<endl; //3
cout<<a[9];
//a++; //错误,没有定义
return 0;
}
因为scoped_array功能有限,不支持动态增长,不支持迭代器,不能搭配STL,所以在需要动态数组的情况下应该使用std::vector,std::vector 是一种可以代替scoped_array 的可选方案,只需要稍微一点的额外代价,可以得到更多的灵活性。scoped_array 是一种不使用动态数组的可选方案。
我的建议是:除非对性能有很严格的要求,否则不要使用 scoped_array。
最后
以上就是外向小蘑菇为你收集整理的boost源码剖析2----内存管理scoped_array的全部内容,希望文章能够帮你解决boost源码剖析2----内存管理scoped_array所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复