/* E:\Program Files\CodeGear\RAD Studio\7.0\include\boost_1_35\boost/checked_delete.hpp 24: */
namespace boost
{
template<class T> inline void checked_delete(T * x)
{
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete x;
}
template<class T> inline void checked_array_delete(T * x)
{
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
(void) sizeof(type_must_be_complete);
delete [] x;
}
template<class T> struct checked_deleter
{
typedef void result_type;
typedef T * argument_type;
void operator()(T * x) const
{
boost::checked_delete(x);
}
};
template<class T> struct checked_array_deleter
{
typedef void result_type;
typedef T * argument_type;
void operator()(T * x) const
{
boost::checked_array_delete(x);
}
};
}
/* E:\Program Files\CodeGear\RAD Studio\7.0\include\boost_1_35\boost/scoped_ptr.hpp 23: */
namespace boost
{
template<class T> class scoped_ptr
{
private:
T * ptr;
scoped_ptr(scoped_ptr const &);
scoped_ptr & operator=(scoped_ptr const &);
typedef scoped_ptr<T> this_type;
public:
typedef T element_type;
explicit scoped_ptr(T * p = 0): ptr(p)
{
}
/*构造函数,存储
p的一份拷贝。注意,
p 必须是用
operator new分配的,或者是null。在构造的时候,
不要求
T必须是一个完整的类型。当指针
p是调用某个allocation函数的结果而不是直接调用
new得到的时
候很有用:因为这个类型不必是完整的,只需要类型
T的一个前置声明就可以了。这个构造函数不会抛出
异常。*/
explicit scoped_ptr(std::auto_ptr<T> p): ptr(p.release())
{
}
/*从一个auto_ptr手中接过控制权,指向auto_ptr指针所指的对象,并且auto_prt指针不再指向该对象*/
~scoped_ptr()
{
boost::checked_delete(ptr);
}
/*删除所指对象。类型
T在被销毁时必须是一个完整的类型。如果
scoped_ptr在它被析构时并没有
占有资源,它就什么都不做。这个析构函数不会抛出异常。*/
void reset(T * p = 0)
{
((p == 0 || p != ptr) ? (void)0 : _assert( "p == 0 || p != ptr", "E:\\Program Files\\CodeGear\\RAD Studio\\7.0\\include\\boost_1_35\\boost/scoped_ptr.hpp", 82));
this_type(p).swap(*this);
}
/*重置一个
scoped_ptr 就是删除它已保存的指针,如果它有的话,并重新保存
p。 通常,资源的生存期
管理应该完全由
scoped_ptr自己处理,但是在极少数时候,资源需要在
scoped_ptr的析构之前释放,或
者
scoped_ptr要处理它原有资源之外的另外一个资源。这时,就可以用
reset,但一定要尽量少用它。
(过多地使用它通常表示有设计方面的问题) 这个函数不会抛出异常。*/
T & operator*() const
{
((ptr != 0) ? (void)0 : _assert( "ptr != 0", "E:\\Program Files\\CodeGear\\RAD Studio\\7.0\\include\\boost_1_35\\boost/scoped_ptr.hpp", 88));
return *ptr;
}
/*返回一个到被保存指针指向的对象的引用。由于不允许空的引用,所以解引用一个拥有空指针
的
scoped_ptr将导致未定义行为。如果不能肯定所含指针是否有效,就用函数
get替代解引用。
这个函数不会抛出异常。*/
T * operator->() const
{
((ptr != 0) ? (void)0 : _assert( "ptr != 0", "E:\\Program Files\\CodeGear\\RAD Studio\\7.0\\include\\boost_1_35\\boost/scoped_ptr.hpp", 94));
return ptr;
}
/*返回保存的指针。如果保存的指针为空,则调用这个函数会导致未定义行为。如果不能确定指针是否
空的,最好使用函数
get。这个函数不会抛出异常。*/
T * get() const
{
return ptr;
}
/*返回保存的指针。应该小心地使用
get,因为它可以直接操作裸指针。但是,
get使得你可以测试保存的
指针是否为空。这个函数不会抛出异常。
get通常用于调用那些需要裸指针的函数。*/
typedef T * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const
{
return ptr == 0? 0: &this_type::ptr;
}
/*返回
scoped_ptr是否为非空。返回值的类型是未指明的,但这个类型可被用于Boolean的上下文中。
在if语句中最好使用这个类型转换函数,而不要用
get去测试
scoped_ptr的有效性*/
bool operator! () const
{
return ptr == 0;
}
void swap(scoped_ptr & b)
{
T * tmp = b.ptr;
b.ptr = ptr;
ptr = tmp;
}
/*交换两个
scoped_ptr的内容。这个函数不会抛出异常。*/
};
template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b)
{
a.swap(b);
}
/*个函数提供了交换两个scoped pointer的内容的更好的方法。之所以说它更好,是因为
swap(scoped1,scoped2) 可以更广泛地用于很多指针类型,包括裸指针和第三方的智能指针。
scoped1.swap(scoped2) 则只能用于它的定义所在的智能指针,而不能用于裸指针。*/
template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
{
return p.get();
}
}
用法:
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 。
区别:
scoped_ptr 与
auto_ptr间的区别主要在于对拥有权的处理。
auto_ptr在复制时会从源
auto_ptr自动交出拥有权,而
scoped_ptr则不允许被复制。