一个作用域指针独占一个动态分配的对象。 对应的类名为 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_;
};