多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > C++智能指針簡單剖析

C++智能指針簡單剖析

來源:程序員人生   發布時間:2014-12-13 08:50:28 閱讀次數:2697次

導讀

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

下面是我在看智能指針時所做的筆記,希望能夠解決你對智能指針的1些困擾。

目錄

  1. 智能指針背后的設計思想
  2. C++智能指針簡單介紹
  3. 為何摒棄auto_ptr?
  4. unique_ptr為什么優于auto_ptr?
  5. 如何選擇智能指針?

正文

1. 智能指針背后的設計思想

我們先來看1個簡單的例子:

void remodel(std::string & str) { std::string * ps = new std::string(str); ... if (weird_thing()) throw exception(); str = *ps; delete ps; return; }

當出現異常時(weird_thing()返回true),delete將不被履行,因此將致使內存泄漏。
如何避免這類問題?有人會說,這還不簡單,直接在throw exception();之前加上delete ps;不就好了。是的,你本應如此,問題是很多人都會忘記在適當的地方加上delete語句(連上述代碼中最后的那句delete語句也會有很多人忘記吧),如果你要對1個龐大的工程進行review,看是不是有這類潛伏的內存泄漏問題,那就是1場災害!
這時候我們會想:當remodel這樣的函數終止(不論是正常終止,還是由于出現了異常而終止),本地變量都將自動從棧內存中刪除―因此指針ps占據的內存將被釋放,如果ps指向的內存也被自動釋放,那該有多好啊。
我們知道析構函數有這個功能。如果ps有1個析構函數,該析構函數將在ps過期時自動釋放它指向的內存。但ps的問題在于,它只是1個常規指針,不是有析構凼數的類對象指針。如果它指向的是對象,則可以在對象過期時,讓它的析構函數刪除指向的內存。

這正是 auto_ptr、unique_ptr和shared_ptr這幾個智能指針背后的設計思想。我簡單的總結下就是:將基本類型指針封裝為類對象指針(這個類肯定是個模板,以適應不同基本類型的需求),并在析構函數里編寫delete語句刪除指針指向的內存空間。

因此,要轉換remodel()函數,應按下面3個步驟進行:

  • 包括頭義件memory(智能指針所在的頭文件);
  • 將指向string的指針替換為指向string的智能指針對象;
  • 刪除delete語句。

下面是使用auto_ptr修改該函數的結果:

# include <memory> void remodel (std::string & str) { std::auto_ptr<std::string> ps (new std::string(str)); ... if (weird_thing ()) throw exception(); str = *ps; // delete ps; NO LONGER NEEDED return; }

2. C++智能指針簡單介紹

STL1共給我們提供了4種智能指針:auto_ptr、unique_ptr、shared_ptr和weak_ptr(本文章暫不討論)。
模板auto_ptr是C++98提供的解決方案,C+11已將將其摒棄,并提供了另外兩種解決方案。但是,雖然auto_ptr被摒棄,但它已使用了好多年:同時,如果您的編譯器不支持其他兩種解決力案,auto_ptr將是唯1的選擇。

使用注意點

  • 所有的智能指針類都有1個explicit構造函數,以指針作為參數。比如auto_ptr的類模板原型為:
    templet<class T> class auto_ptr { explicit auto_ptr(X* p = 0) ; ... };

    因此不能自動將指針轉換為智能指針對象,必須顯式調用:

    shared_ptr<double> pd; double *p_reg = new double; pd = p_reg; // not allowed (implicit conversion) pd = shared_ptr<double>(p_reg); // allowed (explicit conversion) shared_ptr<double> pshared = p_reg; // not allowed (implicit conversion) shared_ptr<double> pshared(p_reg); // allowed (explicit conversion)
  • 對全部3種智能指針都應避免的1點:
    string vacation("I wandered lonely as a cloud."); shared_ptr<string> pvac(&vacation); // No
    pvac過期時,程序將把delete運算符用于非堆內存,這是毛病的。

使用舉例

#include <iostream> #include <string> #include <memory> class report { private: std::string str; public: report(const std::string s) : str(s) { std::cout << "Object created. "; } ~report() { std::cout << "Object deleted. "; } void comment() const { std::cout << str << " "; } }; int main() { { std::auto_ptr<report> ps(new report("using auto ptr")); ps->comment(); } { std::shared_ptr<report> ps(new report("using shared ptr")); ps->comment(); } { std::unique_ptr<report> ps(new report("using unique ptr")); ps->comment(); } return 0; }

3. 為何摒棄auto_ptr?

先來看下面的賦值語句:

auto_ptr< string> ps (new string ("I reigned lonely as a cloud.”); auto_ptr<string> vocation; vocaticn = ps;

上述賦值語句將完成甚么工作呢?如果ps和vocation是常規指針,則兩個指針將指向同1個string對象。這是不能接受的,由于程序將試圖刪除同1個對象兩次――1次是ps過期時,另外一次是vocation過期時。要避免這類問題,方法有多種:

  • 定義
    生活不易,碼農辛苦
    如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
    程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产欧美日韩综合精品一区二区三区 | 超高清欧美同性videos | 四色网站 | 国产1区二区 | 欧美在线亚洲国产免m观看 欧美在线一二三 | 亚洲人成高清 | 国产精品高清一区二区三区不卡 | 性xxxx欧美高清 | 24小时免费观看www日本 | 国产亚洲精品一区久久 | 欧美一区二区精品系列在线观看 | 大胆国模一区二区三区伊人 | 国产精品久久久久久久久久98 | 精品一区二区三区亚洲 | 欧美成人h版 | 中文国产成人精品久久水 | 欧美一级片免费观看 | 一二三中文乱码亚洲乱码 | 性欧美精品| 欧美成性色 | 久久www免费人成看国产片 | www射射一区 | 日韩中文字幕精品免费一区 | 日本精品久久久久中文字幕8 | 国产亚洲精品色一区 | 波多野结衣视频在线观看地址免费 | 亚洲成人中文 | 就要精品综合久久久久五月天 | 精品国产亚洲一区二区三区 | 午夜美女影院 | 最近最新中文字幕大全2019免费视频 | 性色网| 免费一区区三区四区 | 欧美一级在线观看 | 成人毛片18女人毛片 | 精品久久亚洲 | 欧美抽搐一进一进一出 | 国内性经典xxxxx | 亚洲www网站 | 国产精品久久久久久久久久免费 | 男女啪啦猛视频免费 |