头文件: "boost/scoped_ptr.hpp"
boost::scoped_ptr 用于确保动态分配的对象能够被正确地删除。scoped_ptr有着与std::auto_ptr类似的特性,而最大的区别在于它不能转让所有权,然而auto_ptr却可以。事实上,scoped_ptr永远不能被复制或被赋值!scoped_ptr拥有它所指向的资源的所有权,并永远不会放弃这个所有权。scoped_ptr的这种特性改进了代码的表示方式,我们可以根据需要选择最合适的智能指针(scoped_ptr或auto_ptr)。
要决定使用std::auto_ptr还是boost::scoped_ptr, 就要考虑转移所有权是不是你想要的智能指针的一个特性。如果不是,就用scoped_ptr. 它是一种轻量级的智能指针;使用它不会使你的程序变大或变慢。它只会让你的代码更安全,更好维护。
下面是scoped _ptr的模拟实现
template <class T>
class ScopedPtr
{
public:
ScopedPtr( T* ptr )
:_ptr( ptr)
{}
~ScopedPtr()
{
if (_ptr)
{
delete _ptr;
}
}
T&operator*()
{
return *_ptr;
}
T *operator->()
{
return _ptr;
}
T *GetPtr()
{
return _ptr;
}
protected:
ScopedPtr( const ScopedPtr <T> &Sp);
ScopedPtr<T >operator=(const ScopedPtr<T >&Sp);
private:
T*_ptr;
};
ScopedPtr( T* ptr )
构造函数,存储ptr的一份拷贝。注意,ptr 必须是用operator new分配的,或者是null.在构造的时候,不要求T必须是一个完整的类型。当指针p是调用某个分配函数的结果而不是直接调用new得到的时候很有用:因为这个类型不必是完整的,只需要类型T的一个前向声明就可以了。这个构造函数不会抛出异常。
~ScopedPtr()
删除指针所指向的对象。类型T在被销毁时必须是一个完整的类型。如果scoped_ptr在它被析构时并没有保存资源,它就什么都不做。这个析构函数不会抛出异常。
T&operator*()
该运算符返回一个智能指针中存储的指针所指向的对象的引用。由于不允许空的引用,所以解引用一个拥有空指针的scoped_ptr将导致未定义行为。如果不能肯定所含指针是否有效,就用函数GetPtr替代解引用。这个函数不会抛出异常。
T *operator->()
返回智能指针所保存的指针。如果保存的指针为空,则调用这个函数会导致未定义行为。如果不能肯定指针是否空的,最好使用函数GetPtr。这个函数不会抛出异常。
T *GetPtr()
返回保存的指针。应该小心地使用GetPtr,因为它可以直接操作裸指针。但是,GetPtr使得你可以测试保存的指针是否为空。这个函数不会抛出异常。GetPtr通常在调用那些需要裸指针的函数时使用。
用法
scoped_ptr的用法与普通的指针没什么区别;最大的差别在于你不必再记得在指针上调用delete,还有复制是不允许的。典型的指针操作(operator* 和 operator->)都被重载了,并提供了和裸指针一样的语法。用scoped_ptr和用裸指针一样快,也没有大小上的增加,因此它们可以广泛使用。使用boost::scoped_ptr时,包含头文件"boost/scoped_ptr.hpp". 在声明一个scoped_ptr时,用被指物的类型来指定类模板的参数。例如,以下是一个包含std::string指针的scoped_ptr:
boost::scoped_ptr<std::string> p(new std::string("Hello"));
当scoped_ptr被销毁时,它对它所拥有的指针调用delete 。