智能指針可以對動態資源進行管理,保證任何情況下,已經構造的對象能夠安全的自動銷毀。 ...
前言
- 智能指針可以對動態資源進行管理,保證任何情況下,已經構造的對象能夠安全的自動銷毀。說人話就是防止記憶體泄漏。
- C++裡面共有四個智能指針:auto_ptr、unique_ptr、shared_ptr、weak_ptr,第一個已經C++11拋棄,後三個是c++11所支持。
auto_prt 所有權模式
auto_ptr<string> ap1 (new string ("hello,world"));
auto_ptr<string> ap2;
ap2=ap1
//這裡不會報錯,ap2剝奪ap1的許可權,但程式訪問ap1會報錯,ap1被廢棄。auto_ptr缺點是:存在潛在的程式崩潰問題。
unique_ptr 獨占指針
- 獨占指針所指向的記憶體為自己獨有,同一時刻只能有一個unique_ptr。指向給定的對象unique_ptr 對象不支持同類賦值和拷貝。
unique_ptr<int> up1(new int(2333));
unique_ptr<int> up2 = up1;//這裡會報錯,嘗試引用已刪除的函數。
//將原來up1指向記憶體交由up3指向
unique_ptr<int> up3 = std::move(up1);
cout << *up3 << endl;
cout << *up1 << endl;//內部已經將原來的指向設置為了nullptr但是並沒有刪除
//如果是reset帶參調用
unique_ptr<int> up4(new int(2333));
up4.reset(new int(9999));//將原來指向的2333刪除掉重新指向9999
cout << *up4 << endl;
up4 = nullptr;//相當於up4.reset(nullptr);
//cout << *up4 << endl;
unique_ptr<int> up5(new int(777));
int* p5 = up5.release();//將記憶體的控制權交給接受的指針,自己賦值為nullptr,但是沒有刪除
//cout << *up5 << endl;//已經失去了對之前記憶體的控制
cout << *p5 << endl;
delete p5;//需要手動釋放
shared_ptr 共用指針
- 允許多個該智能指針共用一個堆記憶體。通過引用計數來實現共同管理和安全釋放,只有引用計數為0的時候才會刪除該對象的記憶體,支持賦值和拷貝的
shared_ptr<int> sp1(new int(123));
cout << sp1.use_count() << endl;
shared_ptr<int> sp2 = sp1;//增加了引用計數
cout << sp2.use_count() << endl;
cout << *sp1 << " " << *sp2 << endl;
sp1.reset();//對計數進行了減1,並且sp1退出了對共用的記憶體的管理
cout << sp2.use_count() << endl;//1
cout << sp1.use_count() << endl;//0
cout << sp2.unique() << endl;//判斷當前是否為獨占(是否只有一個引用對象)
sp1 = sp2;
cout << sp2.use_count() << endl;//2
cout << sp1.use_count() << endl;//2
//共用指針之間可以交換
shared_ptr<int> sp3(new int(456));
sp2.swap(sp3);//將sp2指向和sp3指向進行了交換,對應的引用計數的變化要清楚
cout << sp1.use_count() << endl;//2
cout << sp2.use_count() << endl;//1
cout << sp3.use_count() << endl;//2
shared_ptr<int> sp4 = sp2;
//獲取共用指針的原始指針
int* p = sp2.get();
cout << p[0] << endl;
p[0] = 321;
cout << *sp4 << endl;
//安全的使用共用指針,推薦使用make_shared函數來進行共用指針對象的創建
shared_ptr<int> sp5 = make_shared<int>();
cout << *sp5 << endl;
shared_ptr<int> sp6 = make_shared<int>(9527);
cout << *sp6 << endl;
shared_ptr<string> sp7 = make_shared<string>(10, '9');
cout << *sp7 << endl;
weak_ptr 弱指針
- 主要是為了配合shared_ptr而引入的一種智能指針,只要為瞭解決迴圈引用的問題。
- 可以從一個shared_ptr或者另一個weak_ptr對象來構造,但是它的構造和析構不會對引用計數產生實質的影響。
- 並且沒有重載*,->這樣的指針操作,也就是說weak_ptr對象是沒有辦法當做指針直接使用的。如果要使用,可以通過lock函數獲得一個shared_ptr對象來使用。
shared_ptr<A> aa = make_shared<A>();
shared_ptr<B> bb = make_shared<B>();
//執行結束以後記憶體沒有被釋放,迴圈引用導致的
aa->b = bb;//2
bb->a = aa;//2
//改用弱指針可以消除迴圈引用的弊端
aa->wb = bb;//1
bb->wa = aa;//1
總結
- 智能指針雖然幫忙管理記憶體,但是帶來程式運行效率的下降。
- 主要根據自己的需求來靈活使用。