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

首頁 > 編程 > C++ > 正文

C++智能指針讀書筆記

2020-05-23 14:12:41
字體:
來源:轉載
供稿:網友
本篇隨筆僅作為個人學習《C++ Primer》智能指針一節后的部分小結,抄書嚴重,伴隨個人理解。主要介紹shared_ptr、make_shared、weak_ptr的用法和聯系
 

最近在補看《C++ Primer Plus》第六版,這的確是本好書,其中關于智能指針的章節解析的非常清晰,一解我以前的多處困惑。C++面試過程中,很多面試官都喜歡問智能指針相關的問題,比如你知道哪些智能指針?shared_ptr的設計原理是什么?如果讓你自己設計一個智能指針,你如何完成?等等……。而且在看開源的C++項目時,也能隨處看到智能指針的影子。這說明智能指針不僅是面試官愛問的題材,更是非常有實用價值。

C++通過一對運算符 new 和 delete 進行動態內存管理,new在動態內存中為對象分配空間并返回一個指向該對象的指針,delete接受一個動態對象的指針,銷毀對象并釋放與之相關的內存。然而這樣的動態內存的使用很危險,因為無法確保始終能在合適的時間釋放內存對象。如果忘記釋放內存,可能造成內存泄露;如果在尚有指針引用內存的情況下釋放內存,會產生非法訪問內存的指針。

C++11中,新的標準庫提供了兩種智能指針(smart pointer)類型來更安全地管理對象。智能指針的使用和常規指針類似,只是它們多了自動釋放所指向的對象的功能。兩種指針的區別在于管理底層指針的方式:shared_ptr允許多個指針指向同一個對象,unique_ptr不支持。標準庫還提供了weak_ptr這一弱指針,指向shared_ptr所管理的對象。三種類型都定義在頭文件memory中。

shared_ptr的使用和vector很相似,在尖括號內說明所指向對象的類型:

 

復制代碼代碼如下:
shared_ptr<string> p1              // p1是shared_ptr,指向string類型
shared_ptr<list<int>> p2     // p2是shared_ptr,指向list的int

 

解引用一個智能指針就能獲得它所指向的對象,在if語句中使用智能指針可以判斷它指向的對象是否為空:

 

復制代碼代碼如下:
// 如果p1非空,檢查p1是否指向一個空的string對象
if (p1 && p1->empty())
    *p1 = "creat";        // 如果p1非空且指向一個空的string對象,解引用p1,為其賦新值creat

 

最安全的分配和使用shared_ptr的方法是調用名為make_shared這一標準庫函數。此函數在動態內存中分配并初始化它,返回指向此對象的shared_ptr。該函數定義在memory中。

make_shared的定義和shared_ptr相似,必須制定要創建對象的類型,如:
 

  1. // 指向一個值為1的int的shared_ptr 
  2. shared_ptr<int> p3 = make_shared<int>)(1); 
  3. // 指向一個值為“www”的string的shared_ptr 
  4. shared_ptr<string> p4 = make_shared<string>(3, "w"); 
  5. // 指向一個初始化的int,值為0 
  6. shared_ptr<int> p5 = make_shared<int>)(); 
?

也可以使用auto定義對象保存make_shared,可以省去書寫shared_ptr的麻煩。

  shared——ptr中有一個關聯的指示器,稱為引用計數??梢钥醋鲆粋€計數器,每當shared_ptr對象進行拷貝操作,如用一個shared_ptr對象初始化另一個shared_ptr對象、作為函數的實參、作為函數返回值時,引用計數都會遞增(視為數值+1)。當賦予shared_ptr新值或者shared_ptr被銷毀時,引用計數遞減。當引用計數減為0,通過析構函數,shared_ptr自動銷毀所管理的對象,釋放內存。

  需要注意的是,如果多個對象共享底層數據,當某一對象被銷毀,不能單方面銷毀底層數據,例如:
 

  1. Blob<string> b1; 
  2. // 新作用域 
  3.   Blob<string> b2 = { "x""b""b" }; 
  4.   b1 = b2; 
  5. }  // 當離開局部作用域,b2被銷毀,然而b2中的元素xbb并不會被銷毀 
  6.    // b1指向最初由b2創建的元素,即“x”, "b", "b",b1依舊可以它們 
?

  weak_ptr是指向shared_ptr管理的對象的一種智能指針,然而它不控制所指向對象的生存期。將一個weak_ptr綁定在shared_ptr上,不會改變shared_ptr的引用計數,一旦最后一個shared_ptr的指向對象被摧銷毀,對象就會被釋放,有無weak_ptr并無卵影響。我的理解是,weak_ptr提供了指向shared_ptr底層數據的功能,控制了shared_ptr對底層數據的訪問。

  因為weak_ptr指向的對象可能不存在(shared_ptr指向的最后一個對象被銷毀時),因而用它不能直接訪問對象,必須調用lock函數檢查其指向的對象是否存在。很容易寫出一個選擇語句進行控制:
 

  1. auto bb = make_shared<string>(2, 'b'); 
  2. weak_ptr<string> xbb(bb); 
  3. if (shared_pr<int> np = xbb.lock()) { // np不為空條件成立 
  4.   // 在if語句內,np和xbb共享對象   
?

補充weak_ptr相關的函數,便于理解:

w.reset 將w置為空
w.use_count() 與w共享對象的個數
w.expired() 若w.use_count()為0,返回true,否則返回false
w.lock() 若w.expired()為true,返回一個空shared_ptr,否則返回一個指向w的對象的shared_ptr

加入《C++ Primer 5th》中的12.19題參照,題中和“智能指針和異常”并未在本篇隨筆中介紹
 

  1. #include <iostream>     
  2. #include <string> 
  3. #include <vector> 
  4. #include <memory> 
  5. #include <initializer_list> 
  6. using namespace std; 
  7. using std::string; 
  8. using std::vector; 
  9. class StrBlobPtr; 
  10. class StrBlob { 
  11. public
  12.   friend class StrBlobPtr;      // 友元 
  13.   StrBlobPtr begin();         // 聲明StrBlob類中的begin()和end() 
  14.   StrBlobPtr end();          // 返回一個指向它自身的StrBlobPtr 
  15. public
  16.   typedef vector<string>::size_type size_type;  // 類型別名,size_type = vector<string>::size_type 
  17.  
  18.   StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {};  // 接受一個initializer_list參數的構造函數將其參數傳                                                            遞給對應的vector構造函數,通過拷貝列表 
  19.   StrBlob::StrBlob() : data(make_shared<vector<string>>()) {};                 // 構造函數,初始化data成員,指向動態分配的vector                                                            中的值初始化vector元素 
  20.   void push_back(const string &t) { data->push_back(t); } 
  21.   string& StrBlob::front() { 
  22.     check(0, "front on empty StrBlob"); 
  23.     return data->front(); 
  24.   } 
  25.   string& StrBlob::back() { 
  26.     check(0, "back on empty StrBlob"); 
  27.     return data->back(); 
  28.   } 
  29.   void StrBlob::pop_back() {             // 刪除尾元素 
  30.     check(0, "pop_back empty StrBlob"); 
  31.     return data->pop_back(); 
  32.   } 
  33.   string& front() const { return data->front(); }; 
  34.   string& back() const { return data->back(); }; 
  35. private
  36.   shared_ptr<vector<string>> data; 
  37.   void StrBlob::check(size_type i, const string &msg) const {  // 檢查元素是否存在 
  38.     if (i >= data->size())                  // 若不存在 
  39.       throw out_of_range(msg);               // 拋出異常 
  40.   } 
  41. }; 
  42. class StrBlobPtr { 
  43. public
  44.   StrBlobPtr() : curr(0) {}; 
  45.   StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}; 
  46.   string & deref() const { 
  47.     auto p = check(curr, "dereference past end"); 
  48.     return (*p)[curr];  // check成功,返回一個p指針,指向make_shared指向的vector 
  49.   }            // 解引用,make_shared獲取vector,用下表運算符返回curr位置上的對象 
  50.   StrBlobPtr& incr() { 
  51.     check(curr, "increment past end of StrBlobPtr"); 
  52.     ++curr; 
  53.     return *this
  54.   } 
  55.   bool operator!=(const StrBlobPtr& p) { return p.curr != curr; } 
  56.  
  57. private
  58.   weak_ptr<vector<string>> wptr; 
  59.   size_t curr; 
  60.   shared_ptr<vector<string>> check(size_t i, const string& msg) const 
  61.   { 
  62.     auto rent = wptr.lock(); 
  63.     if (!rent) 
  64.       throw runtime_error("unbound StrBlobPtr"); 
  65.     if (i >= rent->size()) 
  66.       throw out_of_range(msg); 
  67.     return rent; 
  68.   } 
  69. }; 
  70. StrBlobPtr StrBlob::begin() 
  71.   return StrBlobPtr(*this); 
  72. StrBlobPtr StrBlob::end() 
  73.   return StrBlobPtr(*this, data->size()); 
?


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品一区二区三区久久久| 色综合天天狠天天透天天伊人| 欧美激情伊人电影| 国产在线观看一区二区三区| 黑人精品xxx一区一二区| 国产成人精品在线| www.精品av.com| 国产第一区电影| 久青草国产97香蕉在线视频| 中文字幕亚洲欧美日韩高清| 亚洲aⅴ日韩av电影在线观看| 国产69久久精品成人| 午夜伦理精品一区| 国产欧亚日韩视频| 久久97精品久久久久久久不卡| 国产日韩欧美在线看| 欧美成人精品影院| 欧美激情a∨在线视频播放| 日韩在线观看免费| 亚洲国产成人一区| 国产精品网站入口| 亚洲精品国产品国语在线| 欧美日韩国产精品一区二区不卡中文| 亚洲精品一区中文字幕乱码| 另类美女黄大片| 国产美女精品免费电影| 亚洲美女av网站| 中文字幕国产精品| 911国产网站尤物在线观看| 亚洲人成电影在线观看天堂色| 欧美日韩亚洲一区二| 国产精品一区二区久久精品| 欧美精品在线极品| 日韩欧美aⅴ综合网站发布| 亚洲va欧美va国产综合剧情| 亚洲精品国精品久久99热一| 欧美一级免费视频| 亚洲成人黄色在线观看| 日韩精品亚洲精品| 国产精品亚洲视频在线观看| 国产欧美在线播放| 亚洲а∨天堂久久精品9966| 国产精品久久久久91| 中文字幕久精品免费视频| 91精品视频在线播放| 亚洲一区亚洲二区亚洲三区| 伊人伊成久久人综合网站| 亚洲天堂第二页| 色偷偷偷亚洲综合网另类| 2019国产精品自在线拍国产不卡| 久久影院在线观看| 精品国产一区二区三区久久| 欧美激情日韩图片| 国产原创欧美精品| 亚洲第一页在线| 国内精品模特av私拍在线观看| 91在线观看免费观看| 精品久久久久久| 疯狂蹂躏欧美一区二区精品| 欧美激情精品久久久| 在线a欧美视频| 欧美激情精品久久久久久黑人| 久久久视频精品| 国产综合视频在线观看| 精品久久中文字幕久久av| 亚洲男人av电影| 亚洲精品动漫久久久久| 亚洲国产精品国自产拍av秋霞| www.日韩av.com| 国产99久久精品一区二区永久免费| 成人福利网站在线观看11| 亚洲人成在线免费观看| 久久久久久亚洲| 亚洲女人初尝黑人巨大| 久久99久久99精品中文字幕| 成人精品一区二区三区电影黑人| 日韩电影第一页| 欧美成人午夜视频| 91沈先生作品| 欧美性少妇18aaaa视频| 韩日精品中文字幕| 国产成人综合精品| 欧美人交a欧美精品| 午夜精品视频网站| 亚洲香蕉av在线一区二区三区| 色一情一乱一区二区| 久久久免费在线观看| 欧美激情精品久久久久久蜜臀| 国产一区二区三区18| 久久久久国产视频| 国产精品成人va在线观看| 亚洲一级免费视频| 欧美激情中文字幕在线| 青青久久aⅴ北条麻妃| 26uuu另类亚洲欧美日本一| 亚洲中国色老太| 亚洲精品视频二区| 亚洲国产成人久久综合一区| 在线激情影院一区| 精品一区二区电影| 精品国产乱码久久久久久虫虫漫画| 亚洲自拍偷拍区| 欧美猛男性生活免费| 亚洲乱码国产乱码精品精天堂| 国产日韩欧美影视| 欧美日本国产在线| 欧美做受高潮电影o| 欧美性xxxxxxxxx| 国产欧美最新羞羞视频在线观看| 久久精品视频免费播放| 日韩在线观看免费全集电视剧网站| 日韩精品一区二区三区第95| 国产午夜精品全部视频在线播放| 成人精品福利视频| 黑人与娇小精品av专区| 国产mv久久久| 亚洲美女av在线| 色婷婷亚洲mv天堂mv在影片| 欧美亚洲一级片| 亚洲国产小视频| 欧美福利视频网站| 亚洲第一区第二区| 北条麻妃久久精品| 98精品国产高清在线xxxx天堂| 国产日韩欧美夫妻视频在线观看| 一本色道久久88综合亚洲精品ⅰ| 国产成人一区二区三区| 国产精品欧美风情| xxx欧美精品| 日韩在线欧美在线| 中文字幕一区二区三区电影| 久久影视电视剧免费网站清宫辞电视| 亚洲一区二区三区四区视频| 91在线视频成人| 自拍偷拍亚洲欧美| 91大神在线播放精品| 欧美视频在线观看 亚洲欧| 91高清在线免费观看| 成人免费网站在线观看| 精品无人区太爽高潮在线播放| 国产一区在线播放| 中文字幕日本欧美| 亚洲一区二区三区四区视频| 久久久久久久97| 国产精品欧美久久久| 久久久精品一区二区| 国产精品视频99| 国内外成人免费激情在线视频网站| 午夜精品理论片| 日韩av手机在线看| 日韩美女视频免费在线观看| 国产色视频一区| 欧美激情亚洲精品| 狠狠色狠色综合曰曰| 在线成人免费网站| 91在线观看欧美日韩| 国产精品白嫩初高中害羞小美女| 欧美激情国产精品| 久久九九免费视频| 日韩欧美中文字幕在线播放| 成人国产精品色哟哟| 日本中文字幕久久看| 欧美日韩亚洲视频一区| 亚洲无线码在线一区观看|