RAII&智能指针

  

RAII:资源分配及初始化。但是这个翻译并没有显示出这个惯用法的真正内涵.RAII的好处在于它提供了一种资源自动管理的方式,当出现异常,回滚等现象时,RAII可以正确的释放资源。

内存泄漏会导致:

,,,,,,1.内存耗尽2。其他程序可能用不了3了。程序崩溃

在资源的获取和释放之间,我们通常会使用资源,但常常一些不可预计的异常会在资源使用过程中产生,这就使资源没有得到正确的释放。但是我们其实是可以捕捉异常的,但是捕捉异常会使得代码冗余杂乱,量大而且可读性比较低。

比如:

void  DoSomething ()   {   ,,,int  * p=new  int (1);   ,,,cout<& lt;“DoSomething () & lt; & lt; endl;   }      void 测试()   {   ,,试一试   ,,{   ,,,,,DoSomething ();   ,,}   ,才能赶上(…)   ,,{   ,,,,,delete  p;   ,,,,,扔;   ,,}   }

这样短短一个代码看起来却很杂乱,而且也不好控制。

所以我们引出了智能指针。智能指针的实现原理就是RAII。

下面介绍几个提高库中的智能指针。

<李>

AutoPtr

AutoPtr的实现主要是管理权转移。它没有考虑引用计数,当用一个对象构造另一个对象时,会转移这种拥有关系。

template   class  AutoPtr   {//friend  ostream&, operator<& lt;, & lt; T> (ostream&,操作系统,,const  AutoPtr,,美联社);   公众:   AutoPtr (T *, ptr)   :_ptr (ptr)   {}   ~ AutoPtr ()   {   if  (_ptr !=NULL)   {   delete  _ptr;   }   }   AutoPtr (AutoPtr,,美联社)   :_ptr (ap._ptr)   {   时间=ap._ptr 零;   }   公众:   AutoPtr,,操作符=(const  AutoPtr< T>,,美联社)   {   if (却;能够!=,美联社)   {   delete  _ptr;   时间=_ptr  ap._ptr;   时间=ap._ptr 零;   return  _ptr;   }   }      T&,操作符* ()   {   return  * _ptr;   }   T *,运营商→()   {   return  _ptr;   }   公众:   T *, GetPtr ()   {   return  _ptr;   }      私人:   T *, _ptr;   };

旧版的AutoPtr在它的成员函数中有一个变量所有者,在构架对象的时候所有者为真的。当用它去构建新的对象时,他自己的主人变为假,新对象的所有者为真的。赋值重载的时候也是,新对象的主人是真的。这样在析构的时候只要判断所有者的状态是否为真,当为真时,将这块空间删除即可。

template   class  AutoPtr   {   公众:   AutoPtr (T *, ptr)   :_ptr (ptr)   ,老板(真正的)   {}   ~ AutoPtr ()   {   if (所有者)   {   delete  _ptr;   }   }   AutoPtr (AutoPtr,,美联社)   :_ptr (ap._ptr)   ,老板(真正的)   {   时间=ap._ptr 零;   时间=ap.owner 假;   }   公众:   AutoPtr,,操作符=(const  AutoPtr< T>,,美联社)   {   if (却;能够!=,美联社)   {   delete  _ptr;   时间=_ptr  ap._ptr;   时间=ap.owner 假;   时间=owner 真实;   return  _ptr;   }   }   }

看起来旧的比新的好.AutoPtr最大的缺点就是只能有一个指针管理一块空间,那么为什么新的还取代了旧的呢?看下面

AutoPtr, ap1 (new  int (1));   ,   ,if  (1)   ,   ,{   ,   AutoPtr<才能;int>, ap2 (ap1);   ,   ,}   ,=,* ap1  3;

2。ScopePtr//守卫指针

这个类型的指针简单来说就是简单粗暴的防拷贝。

template   class  ScopedPtr   {   公众:   ScopedPtr (T *, ptr)   :_ptr (ptr)   {}   ~ ScopedPtr ()   {   if  (_ptr  !=, NULL)   {   delete  _ptr;   }   }   保护:   ScopedPtr (const  ScopedPtr,, sp);   ScopedPtr,,操作符=(ScopedPtr,, sp);   公众:   T&,操作符* ()   {   return  * _ptr;   }   T *,运营商→()   {   return  _ptr;   }      私人:   T *, _ptr;   };

将拷贝构造函数和赋值重载函数只声明不实现,而且是保护。就是为了防止在类外实现的情况发生,简单粗暴哈哈。

RAII&智能指针