日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用TR1的智能指针

發布時間:2024/1/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用TR1的智能指针 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作為C++程序員,在沒有智能指針,手動管理內存的蠻荒歲月里,可以說是暗無天日,痛苦異常。直到上帝說,還是要有光,于是智能指針進了標準。C++碼農的日子總算好起來了。

雖然一直鄙視著沒有顯式指針的語言,但是對其自動垃圾回收機制還是翹首以盼的,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();

執行結果:

Ap Construct Use smart pointer to use me

可見,這里沒有調用析構函數,內存泄漏就此發生了,需要在測試代碼中 加入 delete ap補救之,也就是我們以前經常做的事情。

  • shared_ptr基本使用

修改測試代碼:

tr1SharedPoint::spAp ap(new tr1SharedPoint::Ap); ap->pointerOutput();

執行結果:

Ap Construct Use smart pointer to use me Ap Destruct

如此,一個指針的完美閉環就此產生了。我們不需要再手動添加delete語句,等到share_prt的作用域消失時,將自動調用Ap類的析構函數。很多局部鎖的類也是如此構造的;

  • weak_ptr基本使用
    上面的代碼 無法使用weak_ptr直接替換shared_ptr,因為weak_ptr是一種不控制指向對象生存期的智能指針,它指向一個shared_ptr管理的對象.調用lock()將返回一個shared_ptr對象,通過判斷該值可以知道weak_ptr指向的內存是否已經被釋放.
typedef std::tr1::weak_ptr<Ap> wpAp; tr1SharedPoint::wpAp wp = ap;//一個weak_ptr可以直接由一個shared_ptr賦值

測試代碼如下:

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被引用的次數

可是 只了解這么一點知識就可以了么?

答案是,可能是的。如果你只是個總忘記調用delete的C++程序員。有興趣的可以繼續閱讀.

知道更多

按上面的智能指針的用法,我們使用了new運算符,卻沒有顯式的delete,造成了代碼的不對稱感,為了消除這種不對稱,而又使用智能指針,我們最合適的方案是使用make_shared函數來聲明內存的分配,可惜的是,TR1中并沒有包含這個函數,限于本文的標準范圍,我們只能通過boost等三方庫來支持,可是如果使用了boost的內存語法,又沒有必要使用TR1了.一個可能的方案就是把new給封裝起來,眼不見為靜.后期介紹C++11后,我們再來研究現在C++是如何完整的處理動態內存問題的.其實,這個問題在C++ Primer中有很詳細的介紹.

堅持只使用智能指針,就可以避免 1.忘記delete內存 2.使用已經釋放掉的對象 3.同一塊內存釋放兩次 這3類問題,對于一塊內存,只有在沒有任何智能指針指向它的情況下,智能指針才會自動釋放它.

  • 在可能循環引用的類中,使用weak_ptr
    weak_ptr更常用的用法是解決shared_ptr相互引用時的死鎖問題,如果說兩個shared_ptr相互引用,那么這兩個指針的引用計數永遠不可能下降為0,資源永遠不會釋放。
class A; class B;typedef std::tr1::shared_ptr<A> APtr; typedef std::tr1::shared_ptr<B> BPtr; typedef std::tr1::weak_ptr<A> AWeakPtr; typedef std::tr1::weak_ptr<B> BWeakPtr;class A { public:BWeakPtr b; // 注意這里~A () {printf ("A released\n");}};class B { public:AWeakPtr a; // 注意這里~B () {printf ("B released\n");}void output () {printf ("I'm B\n");} };int main () {APtr a(new A());BPtr b(new B());a->b = b;b->a = a;BPtr b2(a->b.lock());b2->output();return 0; }

運行結果

I'm B B released A released

可見,這里的A和B都能被正確釋放了;

  • 使用 std::tr1::enable_shared_from_this 作為基類。比如:
class A : public std::tr1::enable_shared_from_this<A> { public:std::tr1::shared_ptr<A> getSharedPtr() {return shared_from_this();} };

當使用了 shared_ptr 的時候,我們可能需要在所有的地方都使用它,否則就不容易達到管理生存期的目的了。但有的時候,我們手頭上只有對象的原始指針,比如在對象的函數內部,我們只有 this。這就迫切的需要一個功能:如何從對象的裸指針中,生成我們需要的 shared_ptr。

有人可能會覺得這個簡單,shared_ptr a(this); 不就行了么?很遺憾的告訴你,這樣不行,會出問題。為什么呢?因為這里的 a,手中對 this 的引用計數只有 1,它無法知道其他地方智能指針對 this 這個指針(就是這個對象)的引用情況,因此當 a 的生命周期結束(比如函數返回)的時候,this 就會被它毫不留情的釋放掉,其他地方的相關智能指針,手中拿著的該對象指針已經變成非法。因此,我們需要使用std::tr1::enable_shared_from_this 作為基類將類的this指針的引用導出來.

參考閱讀

轉載于:https://www.cnblogs.com/Stultz-Lee/p/9998527.html

總結

以上是生活随笔為你收集整理的使用TR1的智能指针的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。