亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C++11 智能指針

2019-11-14 12:51:05
字體:
來源:轉載
供稿:網友
 

[置頂] c++11智能指針解析——揭開底層面紗,完整理解智能指針

標簽: c++11c++C語言對象2016-01-07 17:00 1531人閱讀 評論(0) 收藏 舉報 分類:

目錄(?)[+]

昨天跟同事小小的研究了下關于不同平臺下的字節對齊問題,起因是遇到了一個坑,vs上沒有問題,在安卓上卻崩潰了。找了半天后發現是c++字節補齊問題,期間包括使用#PRagma pack(1)來限定字節對齊方式等各種條件,也是把我們搞的七暈八素,總算是進一步了解了c++對象結構以及編譯器的操作(有機會的話也補充下字節對齊的理解)。進而想到了智能指針,稍微了解下。第一次接觸智能指針,天知道大學期間自己有多不努力,很多知識點都得留到現在來補齊,所以還是做做筆記吧。

 簡斷截說:c++的入門坑點大家都是有目共睹的,無非就是指針的理解不深導致一些野指針,內存泄露等問題,所以就不贅述。智能指針正好能夠彌補這些問題,因為它本質是存放在棧的模板對象,只是在棧內部包了一層指針。而棧在其生命周期結束時,其中的指針指向的堆內存也自然被釋放了。因而實現了智能管理的效果,不需要考慮內存問題了,其實有點類似某種單例寫法,程序運行結束,也不用考慮單例對象內存問題。

     本次討論:C++11之前的auto_ptr; c++11新加的unique_ptr, shared_ptr以及weak_ptr。

     頭文件:#include <memory>

1.auto_ptr

      auto_ptr是我第一個看的智能指針,也是標準庫里的智能指針,有許多缺陷。

首先看下結構:

從圖中可以看書也是一個模板,使用方法大致類似于vector模板。如下:

[cpp] view plain copy 在CODE上查看代碼片class Base1  {      //__int64 ss;  //public:      bool dd;      int m_itest;  public:      virtual void func(){          cout << "test successed" << endl;      }  };//先寫一個測試類  main函數如下:

[cpp] view%20plain copy int _tmain(int argc, _TCHAR* argv[])  {      auto_ptr <Base1> base1(new Base1);//可理解為先聲明一個名為base1的Base1類型智能指針,然后再base1里面管理new Base1          if (base1.get())//get是智能指針的函數,返回當前當前智能指針對象,即用以判斷是否為空          {           base1->func();            }          return 0;  }  正常用法是這樣,然而我們可以再仔細翻看下底層:

從上圖可以看出,該智能指針成員函數也與vector相似,很容易得出

1、base1.get():返回當前指針對象;

2、base1.release():清空當前智能指針對象,并返回類型指針。所以假如我們要正常刪除,那么需要這樣:

[cpp] view plain copy 在CODE上查看代碼片Base1*base2 = base1.release();  delete base2;  很麻煩對不對,沒關系,還有第三個函數呢

3、base1.reset():從圖中可看出,是重置智能指針,即把內存刪除,且智能指針指向空,但類型不變,所以可以這樣安全便捷地刪除:

[cpp] view%20plain copy base1.reset();  

然而繼續看,還有一個問題:auto_ptr還重載了等號操作符,由圖可知意思是把賦值智能指針的內存交給被賦值智能指針,即如下意思:

[cpp] view plain copy 在CODE上查看代碼片auto_ptr <Base1> base2;  base2 = base1;//將base1的控制權轉交給base2,且base1清空了  base2->func();  因此這樣就有些問題,控制權可以隨便轉換,但是只有一個在用,用起來會受到諸多限制,所以有了下面的智能指針。

介紹之前先上一張別人的表格,來源:http://my.oschina.net/hevakelcj/blog/465978,這是c++11中的智能指針與boost庫中的比較,原本boost就是為完善auto_ptr搞得這些,現在c++11有了,也就不需要再用咯。

2.unique_ptr

 C++11引入了許多便捷的功能,其中也包括這個,在用之前我們可以先看下底層:

可以清楚的看到,unique_ptr中的拷貝構造和賦值操作符delete了,所以也就意味著,他和auto_ptr有區別,控制權唯一,不能隨意轉換。用法都差不多:

[cpp] view plain copy 在CODE上查看代碼片unique_ptr<Base1> base1(new Base1);  unique_ptr<Base1> base2;//但是不能用拷貝構造和等號賦值把base1賦值給base2了  但是如果想切換控制權的話也不是沒有辦法,我們可以看到還有個這樣的函數

要理解這兩個函數,首先要理解c++11引入的move和forward;而要理解move和forward得先理解左值和右值概念。所以還是講全一點吧(已經了解的就直接跳過可以):

補充知識點(其實可以直接看我下一篇更方便理解:點擊打開鏈接):

1、左值與右值:

       左值指的是既能夠出現在等號左邊也能出現在等號右邊的變量(或表達式),右值指的則是只能出現在等號右邊的變量(或表達式)。需要注意的是,左值是指表達式結束后依然存在的持久對象,而右值是指表達式結束時就不再存在的臨時對象。T& 指向的是 lvalue,而 const T& 指向的,卻可能是 lvalue 或 rvalue,左值引用&與右值引用&&(右值引用是c++11加上的)。

2、move和forward:

       需要明確的是,move函數可以是用于構造函數,也可以用于賦值函數,但都需要手動顯示添加。其實move函數用直白點的話來說就是省去拷貝構造和賦值時中間的臨時對象,將資源的內存從一個對象移動到(共享也可以)另一個對象。官話是:c++11 中的 move() 是這樣一個函數,它接受一個參數,然后返回一個該參數對應的右值引用。

       std::forward<T>(u) 有兩個參數:T 與 u。當T為左值引用類型時,u將被轉換為T類型的左值,否則u將被轉換為T類型右值。如此定義std::forward是為了在使用右值引用參數的函數模板中解決參數的完美轉發問題。

其實這里說的不夠清晰,下次翻譯一篇國外的解釋,閱讀下來就能很好理解move這個概念了,這里先不深入。

回到這張圖,這兩個函數體也就很明朗了——重載move版本的拷貝構造函數以及重載move版本的等號賦值函數。

意思就是:把右值的對象(right)移動給左值(_myt&),并且右值清空。

那么用法來了:

[cpp] view plain copy 在CODE上查看代碼片unique_ptr<Base1> base1(new Base1);  unique_ptr<Base1> base2=move(base1);//base1變成empty  unique_ptr<Base1> base3;  base3 = move(base2);//base2變成empty  其它的成員函數就不一一贅述,和auto_ptr大致上是相同的??偨Y,某種程度來說比auto_ptr更為安全,適用部分特殊情況。

3.shared_ptr

如果完全理解了上面兩個ptr的底層,那么shared_ptr的也就容易理解多了。但是和前兩者有很大區別——

前兩者控制權唯一,切換的時候把前面的清除。而shared_ptr不會,照例看下底層:

很顯然,可以直接賦值和調用拷貝構造函數,且不會清空原本的智能指針。用法就很簡單了:

[cpp] view plain copy 在CODE上查看代碼片shared_ptr<Base1> base1(new Base1);  shared_ptr<Base1> base2=base1;  shared_ptr<Base1> base3;  base3 = base2;//三個共享一個  

有個地方需要注意,當刪除一個智能指針時,并不影響其它兩個智能指針的繼續使用。因為該片內存添加了一個引用計數,每shared_ptr一次,引用計數+1;每次調用析構函數,引用計數減一。直到最后一個智能指針刪除,才會釋放內存。

注意:1、在繼續查看時,你會發現以下兩個函數:

其實就是和unique_ptr一樣可以通過move來切換控制權,這個時候是切換,不是共享了。

2、接下來繼續翻看,還有兩個函數:

(其實auto_ptr也有,只是一樣,沒必要截圖了)也就是說,auto_ptr和unique_ptr都可以通過move函數轉換成shared_ptr類型,當然,一樣是切換控制權的形式,即舊的置空。

用法如下:

[cpp] view plain copy 在CODE上查看代碼片auto_ptr<Base1>   base1(new Base1);  shared_ptr<Base1> base2=move(base1);  4.weak_ptrred_ptr

weak_ptr更像是shared_ptr的助手:

1、他不像其余三種,可以通過構造函數直接分配對象內存;他必須通過shared_ptr來共享內存。

2、沒有重載opreator*和->操作符,也就意味著即使分配到對象,他也沒法使用該對象

3、不主動參與引用計數,即,share_ptr釋放了,那么weak_ptr所存的對象也釋放了。

4、使用成員函數use_count()可以查看當前引用計數,expired()判斷引用計數是否為空。

5、lock()函數,返回一個shared_ptr智能指針:

也就是讓weak_ptr觀測shared_ptr智能指針,并且在需要時候通過lock函數返回一個shared_ptr。

6、此外,百科上說:助手類enable_shared_from_this的Shared_from_this會返回this的shared_ptr,所以只需讓要被shared_ptr管理的類繼承它即可。我倒是沒試,有興趣的可以試試,大致意思也就是這般。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
伊人久久综合97精品| 国产精品影片在线观看| 91高清免费在线观看| 欧美成人精品不卡视频在线观看| 精品亚洲永久免费精品| 色噜噜狠狠色综合网图区| 国产精品久久久久久久av大片| 亚洲va欧美va国产综合久久| 国产成人亚洲综合青青| 91国产在线精品| 欧美日韩加勒比精品一区| 亚洲天堂av在线免费| 国产女同一区二区| 亚洲精品国精品久久99热| 国产亚洲精品美女| 国产精品男人的天堂| 国产成人精品国内自产拍免费看| 欧美疯狂xxxx大交乱88av| 2020国产精品视频| 欧美亚洲午夜视频在线观看| 日韩电影网在线| 久久91精品国产91久久跳| 国产午夜一区二区| 欧美在线日韩在线| 亚洲欧美日韩爽爽影院| 日韩色av导航| 久久久伊人欧美| 亚洲一区制服诱惑| 在线成人中文字幕| 欧美成人精品不卡视频在线观看| 亚洲欧美日韩视频一区| 日韩在线播放视频| 亚洲电影中文字幕| 一道本无吗dⅴd在线播放一区| 国产精品日韩久久久久| 欧美亚洲国产日本| 欧美精品在线免费| 久久免费视频在线观看| 中文字幕欧美日韩va免费视频| 国产偷亚洲偷欧美偷精品| 中文字幕日本精品| 日韩精品亚洲视频| 欧美成人午夜激情视频| 国产精品爽爽爽| 欧美性猛交99久久久久99按摩| 日韩av日韩在线观看| 在线观看精品自拍私拍| 538国产精品一区二区免费视频| 国产精品扒开腿做爽爽爽男男| 国产精品欧美一区二区| 日韩国产欧美精品一区二区三区| 久久免费视频这里只有精品| 精品人伦一区二区三区蜜桃网站| 亚洲精品成人网| 欧美美最猛性xxxxxx| 国产综合在线看| 日韩欧美有码在线| 日韩免费在线播放| 91精品啪aⅴ在线观看国产| 久久国产精品久久久久久| 国产成人在线视频| 久久久久一本一区二区青青蜜月| 97国产精品视频人人做人人爱| 中文字幕日韩视频| 另类天堂视频在线观看| 亚洲资源在线看| 国产狼人综合免费视频| 欧美性xxxxx极品娇小| 2019亚洲男人天堂| 国产精品第100页| 日韩av影院在线观看| 日韩激情第一页| 亚洲午夜精品久久久久久久久久久久| 这里只有精品视频| 国产精品黄色影片导航在线观看| 欧美成人性色生活仑片| 68精品国产免费久久久久久婷婷| 久久九九有精品国产23| 亚洲一区二区久久久久久| 日韩高清电影好看的电视剧电影| 亚洲成人在线视频播放| 亚洲精品一区av在线播放| 国产精品欧美日韩| 亚洲女人被黑人巨大进入al| 欧美日韩另类在线| 欧美一区二区三区免费视| 日韩美女视频免费看| 国产视频自拍一区| 97在线免费观看视频| 中文字幕精品一区二区精品| 欧美日韩在线视频一区二区| 国产成人精品优优av| 欧美性xxxxxxx| 92版电视剧仙鹤神针在线观看| 精品国产乱码久久久久久婷婷| 亚洲精品中文字幕av| 精品久久久久久久久中文字幕| 国产精品免费一区二区三区都可以| 国产自产女人91一区在线观看| 亚洲精选在线观看| 亚洲国产日韩欧美综合久久| 日韩亚洲综合在线| 欧美一级在线亚洲天堂| 97av在线播放| 91在线视频成人| 亚洲少妇激情视频| 国产自产女人91一区在线观看| 色先锋资源久久综合5566| 亚洲激情在线观看| 国产精品久久久久秋霞鲁丝| 91地址最新发布| 久久这里只有精品99| 国产精品稀缺呦系列在线| 国产精品美女视频网站| 九色91av视频| 92国产精品久久久久首页| 国产美女精彩久久| 91免费版网站入口| 91视频国产精品| 91中文字幕在线观看| 久久99久久99精品中文字幕| 成人网页在线免费观看| 亚洲国产日韩欧美在线99| 欧美在线亚洲一区| 黄色一区二区在线| 国产精品白丝av嫩草影院| 在线精品高清中文字幕| 中文字幕日韩有码| 一区二区三区 在线观看视| 精品丝袜一区二区三区| 欧美国产日韩二区| 91精品国产综合久久香蕉最新版| 欧美亚洲一区在线| 欧美激情一区二区三区久久久| 日韩有码片在线观看| 热久久免费视频精品| 国产亚洲视频在线| 久久成人精品一区二区三区| 成人精品视频在线| 国产精品一区久久久| 亚洲精品欧美一区二区三区| 综合网中文字幕| 日韩大片免费观看视频播放| 精品视频中文字幕| 国产日本欧美一区二区三区在线| 国产精品看片资源| 日韩精品免费在线播放| 欧美一级大胆视频| 久久久亚洲影院你懂的| 中文字幕亚洲一区二区三区| 色综合久久久888| 中文字幕亚洲字幕| 2020欧美日韩在线视频| 亚洲缚视频在线观看| 亚洲精品日产aⅴ| 欧美国产日韩xxxxx| 久久久综合免费视频| 亚洲一区二区三区xxx视频| 精品国内产的精品视频在线观看| 亚洲天堂一区二区三区| 91精品国产综合久久香蕉922| 久久久亚洲精品视频| 日韩av免费在线看| 色噜噜狠狠狠综合曰曰曰88av|