使用TR1的智能指针
作為C++程序員,在沒有智能指針,手動管理內存的蠻荒歲月里,可以說是暗無天日,痛苦異常。直到上帝說,還是要有光,于是智能指針進了標準。C++碼農(nóng)的日子總算好起來了。
雖然一直鄙視著沒有顯式指針的語言,但是對其自動垃圾回收機制還是翹首以盼的,TR1的智能指針總算可以拿來慰藉下了。
要使用VS2008 SP1的智能指針,我們需要加入頭文件memory.h(linux 下是 tr1\memory.h),
智能指針主要是 auto_ptr, shared_ptr, weak_ptr, unique_ptr ;其中模板auto_ptr是C++98提供的解決方案,C+11已將其摒棄。然而,雖然auto_ptr被摒棄,但它已使用了好多年.因為auto_ptr潛在的內存奔潰問題,所以不推薦使用它,本文也不準備討論該指針.另外unique_ptr在Tr1中還未引入.
Show me The Code
namespace tr1SharedPoint { class Ap { public:Ap(){std::cout << "Ap Construct"<<std::endl;};~Ap(){std::cout << "Ap Destruct"<<std::endl;};void pointerOutput(){std::cout << "Use smart pointer to use me "<<std::endl;} }; typedef std::tr1::shared_ptr<Ap> spAp; }測試代碼
tr1SharedPoint::Ap *ap = new tr1SharedPoint::Ap; ap->pointerOutput();執(zhí)行結果:
Ap Construct Use smart pointer to use me可見,這里沒有調用析構函數(shù),內存泄漏就此發(fā)生了,需要在測試代碼中 加入 delete ap補救之,也就是我們以前經(jīng)常做的事情。
- shared_ptr基本使用
修改測試代碼:
tr1SharedPoint::spAp ap(new tr1SharedPoint::Ap); ap->pointerOutput();執(zhí)行結果:
Ap Construct Use smart pointer to use me Ap Destruct如此,一個指針的完美閉環(huán)就此產(chǎn)生了。我們不需要再手動添加delete語句,等到share_prt的作用域消失時,將自動調用Ap類的析構函數(shù)。很多局部鎖的類也是如此構造的;
- weak_ptr基本使用
 上面的代碼 無法使用weak_ptr直接替換shared_ptr,因為weak_ptr是一種不控制指向對象生存期的智能指針,它指向一個shared_ptr管理的對象.調用lock()將返回一個shared_ptr對象,通過判斷該值可以知道weak_ptr指向的內存是否已經(jīng)被釋放.
測試代碼如下:
tr1SharedPoint::wpAp wp; {tr1SharedPoint::spAp ap(new tr1SharedPoint::Ap);wp = ap;if(wp.lock()){std::cout << "ap not Destruct" <<std::endl;std::cout <<"refence Num " <<wp.use_count() <<std::endl;}ap->pointerOutput(); }if(!wp.lock()){std::cout << "ap IS Destruct" <<std::endl;std::cout <<"refence Num " <<wp.use_count() <<std::endl;}運行結果
Ap Construct ap not Destruct refence Num 1 Use smart pointer to use me Ap Destruct ap IS Destruct refence Num 0以上可知,weak_ptr能通過lock()判斷其管理的shared_ptr是否釋放,通過use_count()知道shared_ptr被引用的次數(shù)
可是 只了解這么一點知識就可以了么?
答案是,可能是的。如果你只是個總忘記調用delete的C++程序員。有興趣的可以繼續(xù)閱讀.
知道更多
按上面的智能指針的用法,我們使用了new運算符,卻沒有顯式的delete,造成了代碼的不對稱感,為了消除這種不對稱,而又使用智能指針,我們最合適的方案是使用make_shared函數(shù)來聲明內存的分配,可惜的是,TR1中并沒有包含這個函數(shù),限于本文的標準范圍,我們只能通過boost等三方庫來支持,可是如果使用了boost的內存語法,又沒有必要使用TR1了.一個可能的方案就是把new給封裝起來,眼不見為靜.后期介紹C++11后,我們再來研究現(xiàn)在C++是如何完整的處理動態(tài)內存問題的.其實,這個問題在C++ Primer中有很詳細的介紹.
堅持只使用智能指針,就可以避免 1.忘記delete內存 2.使用已經(jīng)釋放掉的對象 3.同一塊內存釋放兩次 這3類問題,對于一塊內存,只有在沒有任何智能指針指向它的情況下,智能指針才會自動釋放它.
- 在可能循環(huán)引用的類中,使用weak_ptr
 weak_ptr更常用的用法是解決shared_ptr相互引用時的死鎖問題,如果說兩個shared_ptr相互引用,那么這兩個指針的引用計數(shù)永遠不可能下降為0,資源永遠不會釋放。
運行結果
I'm B B released A released可見,這里的A和B都能被正確釋放了;
- 使用 std::tr1::enable_shared_from_this 作為基類。比如:
當使用了 shared_ptr 的時候,我們可能需要在所有的地方都使用它,否則就不容易達到管理生存期的目的了。但有的時候,我們手頭上只有對象的原始指針,比如在對象的函數(shù)內部,我們只有 this。這就迫切的需要一個功能:如何從對象的裸指針中,生成我們需要的 shared_ptr。
有人可能會覺得這個簡單,shared_ptr a(this); 不就行了么?很遺憾的告訴你,這樣不行,會出問題。為什么呢?因為這里的 a,手中對 this 的引用計數(shù)只有 1,它無法知道其他地方智能指針對 this 這個指針(就是這個對象)的引用情況,因此當 a 的生命周期結束(比如函數(shù)返回)的時候,this 就會被它毫不留情的釋放掉,其他地方的相關智能指針,手中拿著的該對象指針已經(jīng)變成非法。因此,我們需要使用std::tr1::enable_shared_from_this 作為基類將類的this指針的引用導出來.
參考閱讀
轉載于:https://www.cnblogs.com/Stultz-Lee/p/9998527.html
總結
以上是生活随笔為你收集整理的使用TR1的智能指针的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Linux基础命令---comm
- 下一篇: 漫谈 Windows Server 管理
