/* 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", 8 ![]() 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) 可以更广泛地用于很多指针类型,包括裸指针和第三方的智能指针。 [2] scoped1.swap(scoped2) 则只能用于它的定义所在的智能指针,而不能用于裸指针。*/ template<class T> inline T * get_pointer(scoped_ptr<T> const & p) { return p.get(); } } 用法: scoped_ptr的用法与普通的指针没什么区别;最大的差别在于你不必再记得在指针上调用delete,还有复制是不允许的。典型的指针操作(operator* 和 operator-> ![]() boost::scoped_ptr<std::string> p(new std::string("Hello" ![]() 当scoped_ptr被销毁时,它对它所拥有的指针调用delete 。 区别: scoped_ptr 与 auto_ptr间的区别主要在于对拥有权的处理。auto_ptr在复制时会从源auto_ptr自动交出拥有权,而scoped_ptr则不允许被复制。 |
boost:: scoped_ptr源码剖析
最新推荐文章于 2023-04-05 00:46:23 发布