智能指针 shared_ptr 解析
LinJM ? @HQU
shared_ptr是一個智能指針。在C++ 11頒布之前,它包括在TR1(Technical Report 1)其中,如今囊括在C++11的標準庫中。智能指針
智能指針(Smart pointers)是存儲“指向動態分配(在堆上)的對象的指針”的對象。也就是說。智能指針事實上是個對象。只是它的行為非常像C++的內建指針,僅僅是它們能夠在適當的時候自己主動刪除它們所指向的對象。智能指針在面對異常時有非常顯著的作用,它們能夠確保動態分配對象的全然析構。它們還能夠用于跟蹤多主人共享的動態分配對象。
在概念上,智能指針能夠看作擁有它所指向的對象,并因此在對象不再須要時負責將它刪除。
假設對智能指針的概念還不是非常清晰,再看以下的介紹:
A smart pointer is anabstract data type that simulates a pointer while providing additional features, such as automatic memory management or bounds checking. These additional features are intended to reduce bugs caused by the misuse of pointers while retaining efficiency. Smart pointers typically keep track of the memory they point to. They may also be used to manage other resources, such as network connections and file handles. ? ??Misuse of pointers is a major source of bugs.Smart pointers prevent most situations of memory leaks by making the memory deallocation automatic.More generally, they make object destruction automatic: the object controlled by a smart pointer is automatically destroyed (finalized and then deallocated) when the last (or only) owner of the object is destroyed, for example because the owner is a local variable, and execution leaves the variable's scope. Smart pointers also eliminate dangling pointers by postponing destruction until the object is no longer in use.
shared_ptr
前面已經說了shared_ptr是個智能指針。類似于vector。智能指針也是模板。因此,當我們創建一個智能指針時,必須提供額外的信息——指針能夠指向的類型。與vector一樣,我們在尖括號內給出類型,之后是所定義的這樣的智能指針的名字:
shared_ptr<string> p1; // shared_ptr,能夠指向string shared_ptr<list<int>> p2; // shared_ptr,能夠指向int的list默認初始化的智能指針中保存著一個空指針。
智能指針的使用方式與普通指針類似。解引用一個智能指針返回它指向的對象。
假設在一個條件推斷中使用智能指針,效果就是檢測它是否為空:
//假設p1不為空,檢查它是否指向一個空string if (p1 && p1->empty())*p1 = "hi"; // 假設p1指向一個空string,解引用p1。將一個新值賦予string以下列出shared_ptr支持的操作:
| shared_ptr<T> p | 空智能指針。能夠指向類型為T的對象 |
| p | 將p用作一個條件推斷,若p指向一個對象,則為true |
| *p | 解引用p,獲得它所指向的對象 |
| p->mem | 等價于(*p).mem |
| p.get() | 返回p中保存的指針。 要小心使用。若智能指針釋放了其對象,返回指針所指向的對象 也就消失了 |
| swap(p,q)或p.swap(q) | 交換p和q的指針 |
| make_shared<T>(args) | 返回一個shared_ptr,指向一個動態分配的類型為T的對象。使用args初始化此對象 |
| shared_ptr<T> p(q) | p是shared_ptr q的拷貝;此操作會遞增q中的計數器。 q中的指針 必須能轉化為T* |
| p=q | p和q都是shared_ptr,所保存的指針必須能相互轉換。此操作會 遞減p的引用計數,遞增q的引用計數 |
| p.unique() | 若p.use_count()為1。返回true,否則返回false |
| p.use_count() | 返回與p共享對象的智能指針數量:可能非常慢。主要用于調試 |
樣例:
//p3指向一個值為42的int的shared_ptr shared_ptr<int> p3 = make_shared<int>(42); //p4指向一個值為“99999999”的string shared_ptr<string> p4 = make_shared<string>(10,'9');以對象管理資源
上面我們對shared_ptr進行了初步的介紹。只是它的長處我們還沒開始闡述。shared_ptr的一個重大長處就是它實現了“以對象管理資源”這個資源管理思想。所謂資源就是,一旦使用了它。將來必須還給系統。在C++中最常使用的資源就是動態分配內存(假設你分配內存卻從未歸還過,那就會導致內存泄漏),主要通過一對運算符來完畢:new,在動態內存中為對象分配空間并返回一個指向該對象的指針。我們能夠選擇對對象進行初始化。delete,接受一個動態對象的指針。銷毀該對象,并釋放與之相關聯的內存。
動態內存的使用非常easy出現故障,由于確保在正確的時間釋放內存是極其困難的。有時候我們會忘記釋放內存。在這樣的情況下就會產生內存泄漏。有時在尚有指針引用內存的情況下我們就釋放了它,在這樣的情況下就會產生非法引用內存的指針。
那么,為了更easy(同一時候更安全)地使用動態內存,我們須要使用智能指針類型來管理動態對象。在C++11之前,C++的標準庫提供了auto_ptr來管理動態對象,而tr1中提供了shared_ptr。如今C++11新的標準庫將tr1的內容包括進去,提供了兩種智能指針來管理動態對象,這兩種智能指針的差別在于管理底層指針的方式:shared_ptr同意多個指針指向同一個對象。unique_ptr則“獨占”所指向的對象。標準庫還定義了一個名為weak_ptr的伴隨類。它是一種弱引用。指向shared_ptr所管理的對象。這三種類型都定義在memory頭文件里。
以下用一個樣例來分析資源管理。
如果我們有一個class Investment,當中包括一個函數createInvestment()供應我們某特定的Investment對象:
// 返回指針,指向Investment繼承體系內的動態分配對象。調用者有責任刪除它。// 這里為了簡化,刻意不寫參數 Investment * createInvestment();
一如凝視所言。createInvestment的調用端使用了函數返回的對象后,有責任刪除之。如今考慮有個f()函數履行這個責任:
void f() {Investment * pInv = createInvestment();....delete pInv; }這看起來妥當,但在若干情況下f()可能無法刪除它得自createInvestment的對象——也許由于“....”區域中一個過早的return語句或者異常返回,這樣程序的控制流就絕不會觸及delete語句。從而造成內存泄漏。
當然啦。慎重地編敲代碼能夠防止這一類錯誤,可是你必須想想。代碼可能會在時間漸漸過去后被改動。
一旦軟件開始維護,可能有人加入了return語句。
因此,單純地依賴“f()總是會運行其delete語句”是行不通的。
那我們該怎么辦呢?非常easy——以對象管理資源。
把資源放進對象內,當控制流離開f( )。該對象的析構函數會自己主動釋放那些資源。
void f() {std::tr1::shared_ptr<Investment> pInv(createInvestment());..... }這個簡單的樣例示范了“以對象管理資源”的兩個關鍵想法:
- 獲得資源后立馬放進管理對象內。
以上代碼中createInvestment返回的資源被當作其管理者shared_ptr的初值。實際上“以對象管理資源”的觀念常被稱為“資源取得時機便是初始化時機”,由于我們差點兒總是在獲得一筆資源后于同一語句內以它初始化某個管理對象。
- 管理對象運用析構函數確保資源被釋放。不論控制流怎樣離開區塊。一旦對象被銷毀其析構函數自然會被自己主動調用。于是資源被釋放。
假設能夠,我推薦你看看《C++ Primer》5th 的第12章,里面比較系統地介紹了shared_ptr的用法!
!!。假設你想深入了解shared_ptr,那么Ref[6]值得學習。
Refs:
[1] Stanley B.Lippman. C++ Primer 5th 中文版.電子工業出版社, 2013.
[2] Scott Meyers. Effective C++ 中文版.電子工業出版社, 2011.
[3] Boost C++ libraries:Smart Pointers 智能指針.
[4] Boost C++ libraries:shared_ptr類模板
[5]?John M. Dlugosz.?Smart Pointers Overview
[6]?std::tr1::shared_ptr源代碼賞析
[7]?Yonat Sharon.?Smart Pointers - What, Why, Which?
本文地址:http://blog.csdn.net/linj_m/article/details/25045403
很多其它相關資源 請關注博客:LinJM-機器視覺?微博:林建民-機器視覺
轉載于:https://www.cnblogs.com/mfrbuaa/p/5088673.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的智能指针 shared_ptr 解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysqldump: Couldn't
- 下一篇: 管理集群中的 crs 管理员