C++——智能指针
C++的內存管理是一個很大的問題,C++程序員總是會無意間的造成內存泄漏的問題,C++98給出了智能指針的解決方案,智能指針會在銷毀指針的時候自動銷毀指針指向的內容(例如棧解退)。
智能指針是一個模板類,可以看成一個被包裝過的指針。他的構造函數如下
template <class X> class auto_ptr { public:explicit auto_ptr(X * p=0) throw() {} };他將獲得一個指向X的指針。
使用智能指針后的程序
#include <iostream> #include <string> #include <memory> using namespace std;int main() {auto_ptr<string> ps(new string ("hello"));//don't need deletecout << *ps;return 0; }運行結果
在只能指針ps被銷毀的時候,會調用其析構函數釋放ps指向的內容。
我們也可以寫一個自己的簡單的智能指針
include <iostream> #include <string> #include <memory> using namespace std; template <class T> class my_auto_ptr { private:T * ptr; public:explicit my_auto_ptr(T * p= nullptr) : ptr(p) {}~my_auto_ptr(){delete ptr;}T & operator*(){return *ptr;} }; int main() {my_auto_ptr<string> ps (new string("hello"));cout << *ps;return 0; }想進一步包裝的話還可以重載-> =等運算符。
這種智能指針(auto_ptr)在進行賦值運算時可能會有問題,又或者是不經意間重復釋放內存,有以下幾種解決方案
1.重載=進行深拷貝
2.建立所有權的概念,每個對象只有一個智能指針擁有它,=是所有權的轉讓
unique_ptr
3.創建智能性更高的指針,記錄構造函數和析構函數的次數,判斷是否釋放。
shared_ptr
?unique_ptr的使用比較嚴格
編譯器不允許將將這類對象賦值給另一個對象,但如果對象是一個臨時的右值則可以(如返回值)。
int main() {unique_ptr<string> ps;unique_ptr<string> pd;pd = ps; //errorreturn 0; }?這樣可以,這將"hello"的所有權從temp變成了主函數中的ps
unique_ptr<string> t(const char * s) {unique_ptr<string> temp(new string(s));return temp; } int main() {unique_ptr<string> ps;ps = t("hello");cout << *ps;return 0; }注意:智能指針的本質也是使用new和delete,其中,只有unique_ptr有[]delete的版本,不要讓只能指針指向非new出來的對象。
?在unique_ptr為右值時,可將其賦值給shared_ptr,因為后者是計數處理。
shared_ptr有一個構造函數,可將右值unique_prt轉換為shared_prt,shared_ptr將接管原來unique_prt接管的對象。
智能指針的選擇
如果要將多個指針指向同一個對象,應選擇shared_ptr
SLT很多算法都支持賦值和賦值操作,可用于shared_prt
不需要用多個指針指向同一個對象,?可使用unique_ptr
用new分配的內存,并返回該內存的指針,unique_prt是個不錯的選擇
總結
- 上一篇: pxcook
- 下一篇: 【c++复习笔记】——智能指针详细解析(