当前位置: 代码迷 >> 综合 >> boost::scoped_ptr 源码分析
  详细解决方案

boost::scoped_ptr 源码分析

热度:15   发布时间:2024-01-09 16:15:13.0

一个作用域指针独占一个动态分配的对象。 对应的类名为    boost::scoped_ptr,它的定义在 boost/scoped_ptr.hpp 中。 不像    std::auto_ptr,一个作用域指针不能传递它所包含的对象的所有权到另一个作用域指针。    一旦用一个地址来初始化,这个动态分配的对象将在析构阶段释放。

因为一个作用域指针只是简单保存和独占一个内存地址,所以 boost::scoped_ptr的实现就要比 std::auto_ptr 简单。 在不需要所有权传递的时候应该优先使用    boost::scoped_ptr 。 在这些情况下,比起    std::auto_ptr 它是一个更好的选择,因为可以避免不经意间的所有权传递。

我们通过下面的例子,可以了解scoped_ptr如何使用

#include <boost/scoped_ptr.hpp>
#include <iostream>

using namespace std;

int main()
{
    boost::scoped_ptr<int> i(new int);
    *i = 1;
    cout << "print the value by *i " << *i << endl;

    *i.get() = 2;
    cout << "print the value and assignment by get() " <<  *i.get() << endl;

    return 0;
}

 

===========The result is=====================

print the value by *i 1
print the value and assignment by get() 2

 

        一经初始化,智能指针 boost::scoped_ptr所包含的对象,可以通过类似于普通指针的接口来访问。 这是因为重载了相关的操作符    operator*()operator->()operator bool() 。 此外,还有    get()reset() 方法。    前者返回所含对象的地址,后者用一个新的对象来重新初始化智能指针。 在这种情况下,新创建的对象赋值之前会先自动释放所包含的对象。boost::scoped_ptr 的析构函数中使用    delete 操作符来释放所包含的对象。 这对    boost::scoped_ptr 所包含的类型加上了一条重要的限制。boost::scoped_ptr 不能用动态分配的数组来做初始化,因为这需要调用    delete[] 来释放。 在这种情况下,可以使用下面将要介绍的boost:scoped_array

       如果我们在操作中不小心把已有的scoped_ptr对象赋值给其他scoped_ptr, boost::scoped_ptr<int> ii(i)。程序会报错的:../boost_1_49_0/boost/smart_ptr/scoped_ptr.hpp:45:5: 错误:‘boost::scoped_ptr<T>::scoped_ptr(const boost::scoped_ptr<T>&) [with T = int, boost::scoped_ptr<T> =
 boost::scoped_ptr<int>]’是私有的。我们可以通过Scoped_ptr的源码来分析其中的理由:

class scoped_ptr
{
public:
  // Constructor.
  explicit scoped_ptr(T* p = 0)    //通过这里我们发现scoped_ptr是不允许在初始化这样使用scoped_ptr<int> i = new int 的。因为他们explicit的,是不能隐式转换的。
    : p_(p)
  {
  }

  // Destructor.
  ~scoped_ptr()
  {
    delete p_;    //调用的是delete,故不能指向数组
  }

  // Access.
  T* get()
  {
    return p_;
  }

  // Access.
  T* operator->()
  {
    return p_;
  }

  // Dereference.
  T& operator*()
  {
    return *p_;
  }

  // Reset pointer.
  void reset(T* p = 0)
  {
    delete p_;
    p_ = p;
  }

private:
  // Disallow copying and assignment.       所有权不能传递的秘密在着呢。
  scoped_ptr(const scoped_ptr&);
  scoped_ptr& operator=(const scoped_ptr&);

  T* p_;
};