智能指针scoped_ptr组件的使用

scoped_ptr是一个行为很类似标准库中的auto_ptr智能指针,它包装了new操作符在椎上分配的动态对象,能够保证动态创建的对象在任何时候都能够被正确的删除。

但是scoped_ptr的所有权更加严格,不允许转让,对其赋值和拷贝都是不合法行为,因而显得更轻巧和快捷。

scoped_ptr重载了operator*()和operator->()解引用操作符*和箭头操作符->,因此可以把scoped_ptr对象如同指针一样使用。如果scoped_ptr保存的空指针,那么这两个操作的行为未定义。

scoped_ptr不能在两个scoped_ptr之间、scoped_ptr与原始指针之间或空指针之间进行了相等或不相等测试。operator ==和operator !=都被声明为私有。

下面是scoped_ptr类摘要

template<class T> class scoped_ptr // noncopyable
{
private:

    T * px;
    scoped_ptr(scoped_ptr const &);
    scoped_ptr & operator=(scoped_ptr const &);
    typedef scoped_ptr<T> this_type;
    void operator==( scoped_ptr const& ) const;
    void operator!=( scoped_ptr const& ) const;

public:

    typedef T element_type;
    explicit scoped_ptr( T * p = 0 ); // never throws
    explicit scoped_ptr( std::auto_ptr<T> p ); // never throws

    ~scoped_ptr() // never throws在其作用域结束时自动删除保存的指针对象,从而正确地回收资源
    void reset(T * p = 0) // never throws删除原来保存的指针,再保存新的指针p,如果p是空指针,那scoped_ptr将不持有任何指针
    {
        BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
        this_type(p).swap(*this);
    }

    T & operator*() const // never throws
    {
        BOOST_ASSERT( px != 0 );
        return *px;
    }

    T * operator->() const // never throws
    {
        BOOST_ASSERT( px != 0 );
        return px;
    }

    T * get() const // never throws返回scoped_ptr内部保存的原始指针
    {
        return px;
    }

    void swap(scoped_ptr & b);// never throws交换两个scoped_ptr保存的原始指针
};

scoped_ptr有两个好处:一是使代码更加清晰简单,而简单意味着更少的错误。二是它并没有增加多余的操作,安全的同时保证效率,可以获得与原始指针同样的速度。

使用范例:

 

#include <iostream>
#include <string>
#include <boost/smart_ptr.hpp>
using namespace boost;
using namespace std;
struct posix_file{
  posix_file(const char* file_name){
   cout << "Open file:" << file_name << endl;
   }
   ~posix_file(){cout << "close file" << endl;}
};
int main(){
	/*
	//note:Don't try to use 'delete' again,
	//scoped_ptr help us destory resource automatically
	//scoped_ptr is a pointer-behavior-like object,but it isn't a pointer
	//Even if you use 'delete' it wouldn't work
	//scoped_ptr do not support assignment and copy
	//it can only use operator * and -> ,sp++ ,sp = sp2.etc. are illegal usage here
	*/
	/*exmple1*/
   scoped_ptr<string> sp(new string("Hello,ajioy!"));
   cout << *sp << endl;
   cout << sp->size() << endl;
   
   /*exmaple2*/
   scoped_ptr<int> p(new int);//equal int *p;
   if(p){ //test p is valid
   	*p = 100;
   	cout << *p << endl;
   }
   p.reset();//make p null
   assert(p == 0);
   if(!p)
   {cout << "scoped_ptr == null" << endl;}
   scoped_ptr<posix_file> fp(new posix_file("/tmp/a.txt"));
   //destructor scoped_ptr here
   //p and fp are deleted automatically
   	
}


运行结果:

Hello,ajioy!
12
100
scoped_ptr == null
Open file:/tmp/a.txt
close file 

与auto_ptr的区别

两者的根本性区别在于指针的所有权。auto_ptr特意被设计成可以移交所有权的,而scoped_ptr刚好相反。

scoped_ptr明确地表明了代码原始者的意图:只能在定义的作用域内使用,不可转让。

scoped_ptr在大多情况下可以与auto_ptr互换,且可以从一个auto_ptr获得指针的所有权(同时auto_ptr失去管理权)。

两者均有缺陷,都不能作为容器的元素,不过原因不同:auto_ptr是因为它的转移语义,而scoped_ptr是因为不支持拷贝和赋值,不符合容器对元素类型的要求。

使用示例:

#include <iostream>
#include <boost/smart_ptr.hpp>
using namespace boost;
using namespace std;
int main(){
  auto_ptr<int> ap(new int(10));
  scoped_ptr<int> sp(ap);//get original pointer from auto_ptr 
  assert(ap.get() == 0);//The original auto_ptr no longer owns the pointer
  
  ap.reset(new int(20));//auto_ptr holds a new pointer
  cout << *ap << "," << *sp << endl;
  
  auto_ptr<int> ap2;
  ap2 = ap;//ap2 gets the orginal pointer from ap,transfer ownership
  assert(ap.get() == 0);//ap no longer owns a pointer
  scoped_ptr<int> sp2;
 // sp2 = sp; it won't compile
}


运行结果:

20,10

你可能感兴趣的:(String,object,File,null,delete,FP)