boost源码剖析2----内存管理scoped_array

从名字可以看得出来,与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 <boost\smart_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。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值