智能指针

智能指针(英語:Smart pointer)是一種抽象的資料類型。在程式設計中,它通常是經由类模板來實作,藉由模板來達成泛型,藉由類別的解構函數來達成自動釋放指標所指向的記憶體或物件。

C++中的智能指针[编辑]

auto_ptr[编辑]

auto_ptr這個類別模板被定義在ISO/IEC 14882的第20.4.5章節裡:

namespace std {      template <class Y> struct auto_ptr_ref {};      template <class X>     class auto_ptr {     public:         typedef X element_type;          // 20.4.5.1 construct/copy/destroy:         explicit           auto_ptr(X* p =0)throw();                            auto_ptr(auto_ptr&)throw();         template <class Y> auto_ptr(auto_ptr<Y>&)throw();          auto_ptr&                      operator=(auto_ptr&)throw();         template <class Y> auto_ptr&   operator=(auto_ptr<Y>&)throw();         auto_ptr&                      operator=(auto_ptr_ref<X>)throw();          ~auto_ptr() throw();          // 20.4.5.2 members:         X&     operator*() const throw();         X*     operator->() const throw();         X*     get() const throw();         X*     release() throw();         void   reset(X* p =0)throw();          // 20.4.5.3 conversions:         auto_ptr(auto_ptr_ref<X>)throw();         template <class Y> operator auto_ptr_ref<Y>() throw();         template <class Y> operator auto_ptr<Y>() throw();     };  } 

unique_ptr[编辑]

C++11中提供了std::unique_ptr,定义在<memory>头文件中。

C++11新增了move语义,相比copy语义,它能更好的实现值传递.std::auto_ptr使用的是copy语义,为了向后兼容,C++11没有修改std::auto_ptr,而是引入了新的使用move语义的std::unique_ptr.

unique_ptr的拷贝构造函数和赋值运算符都声明为deleted,也就是说它不能被拷贝,只能通过std::move来转递它所指向的内存的所有权。

std::unique_ptr<int> p1(new int(5)); std::unique_ptr<int> p2 = p1; // 编译会出错 std::unique_ptr<int> p3 = std::move (p1); // 转移所有权,现在那块内存归p3所有, p1成为无效的指针。  p3.reset(); //释放内存。 p1.reset(); //实际上什么都没做。 

std::auto_ptr依然存在,但在C++11中被标为"弃用".

shared_ptr和weak_ptr[编辑]

基于Boost库, C++11加入了shared_ptrweak_ptr.它们最早在TR1中就被引入,但在C++11中,在Boost的基础上又加入了新的功能。

std::shared_ptr使用引用计数。每一个shared_ptr的拷贝都指向相同的内存。在最后一个shared_ptr析构的时候,内存才会被释放。

std::shared_ptr<int> p1(new int(5)); std::shared_ptr<int> p2 = p1; // 都指向同一内存。  p1.reset(); // 因为p2还在,所以内存没有释放。 p2.reset(); // 释放内存,因为没有shared_ptr指向那块内存了。 

std::shared_ptr使用引用计数,所以有循环计数的问题。为了打破循环,可以使用std::weak_ptr.顾名思义, weak_ptr是一个弱引用,只引用,不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。所以weak_ptr不保证它指向的内存一定是有效的,在使用之前需要检查。

std::shared_ptr<int> p1(new int(5)); std::weak_ptr<int> wp1 = p1; // 还是只有p1有所有权。  {   std::shared_ptr<int> p2 = wp1.lock(); // p1和p2都有所有权   if (p2) // 使用前需要检查   {      // 使用p2   } } // p2析构了,现在只有p1有所有权。  p1.reset(); // 内存被释放。  std::shared_ptr<int> p3 = wp1.lock(); // 因为内存已经被释放了,所以得到的是空指针。 ifp3 {   // 不会执行到这。 } 

外部連結[编辑]