• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            我的第一本C++書(shū)

            游歷C++世界的地圖

            C++小品:weak_ptr與傳達(dá)室的花名冊(cè)

            原文來(lái)自

            http://imcc.blogbus.com/logs/162618478.html

            在C++11中,我們可以使用shared_ptr管理某個(gè)對(duì)象的所有權(quán),負(fù)責(zé)對(duì)象的析構(gòu)。然而在某些情況下,我們只是希望安全的訪問(wèn)某個(gè)對(duì)象,而不想擁有這個(gè)對(duì)象的所有權(quán),對(duì)這個(gè)的析構(gòu)負(fù)責(zé)(有點(diǎn)像電視劇中的那些不負(fù)責(zé)任的男人哦,只是玩玩而已,不會(huì)負(fù)責(zé))。在這種情況下,我們可以使用表示弱引用的weak_ptr。

            weak_ptr可以由一個(gè)shared_ptr構(gòu)建,表示這個(gè)weak_ptr擁有這個(gè)shared_ptr所指向的對(duì)象的訪問(wèn)權(quán),注意,這里僅僅是訪問(wèn)權(quán),它不會(huì)改變智能指針的引用計(jì)數(shù),自然也就不會(huì)去析構(gòu)這個(gè)對(duì)象。利用weak_ptr,我們就可以安全地訪問(wèn)那些不具備所有權(quán)的對(duì)象。

            一個(gè)現(xiàn)實(shí)中的例子就是學(xué)校的傳達(dá)室,傳達(dá)室擁有一本學(xué)生的名單,如果某個(gè)電話來(lái)了找某個(gè)學(xué)生,傳達(dá)室會(huì)根據(jù)花名冊(cè)去嘗試訪問(wèn)這個(gè)學(xué)生,如果這個(gè)學(xué)生還在學(xué)校,就直接呼叫這個(gè)學(xué)生,如果已經(jīng)離開(kāi)了,這給這個(gè)學(xué)生留一個(gè)消息。在這里,花名冊(cè)上的學(xué)生可能還在學(xué)校(對(duì)象還存在),也可能已經(jīng)離開(kāi)學(xué)校(對(duì)象已經(jīng)析構(gòu)),我們都需要對(duì)其進(jìn)行訪問(wèn),而weak_ptr就是用來(lái)訪問(wèn)這種不確定是否存在的對(duì)象的。

            #include <iostream>
            #include <map>
            #include <algorithm>
            #include <memory>
            using namespace std;

            // 學(xué)校的同學(xué)
            class human
            {
            public:
            human(string _n):name(_n)
            {};
            ~human()
            {
            cout<<name<<" was destructed."<<endl;
            }
            void call() // 嘿,有個(gè)電話找你
            {
            cout<<name<<" was called."<<endl;
            }
            private:
            string name;
            };
            // 傳達(dá)室
            class doorman
            {
            public:
            doorman(map<string,shared_ptr<human>> humans)
            {
            // 根據(jù)學(xué)生對(duì)象構(gòu)造花名冊(cè),注意其中保存的是有shared_ptr構(gòu)造的weak_ptr
            for_each(humans.begin(),humans.end(),
            [&names](pair<string,shared_ptr<human>> h)
            {
            names[h.first] = weak_ptr<human>(h.second);
            });
            }
            // 有個(gè)電話打到了傳達(dá)室
            void call(string name)
            {
            // 找找看,花名冊(cè)中有沒(méi)有這個(gè)學(xué)生
            auto it = names.find(name);
            // 如果有
            if(it!=names.end())
            {
            auto man = (*it).second;
            // 用lock()函數(shù)嘗試獲得weak_ptr所指向的shared_ptr,保存為p
            if(auto p = man.lock())
            p->call(); // 如果找到關(guān)聯(lián)的shared_ptr,也就是這個(gè)對(duì)象還存在,也就是這個(gè)學(xué)生還在學(xué)校,呼叫之
            else // 如果無(wú)法得到關(guān)聯(lián)的shared_ptr,表示這個(gè)對(duì)象已經(jīng)不存在了,學(xué)生離開(kāi)了學(xué)校,只能給他留一個(gè)消息了
            {
            leavemsg(name);
            }
            }
            else // 如果花名冊(cè)中根本沒(méi)有這個(gè)名字
            {
            cout<<name<<" is not in the school."<<endl;
            }
            }
            void leavemsg(string name)
            {
            cout<<name<<" has left school.I will leave a message for him."<<endl;
            }
            private:
            map<string,weak_ptr<human>> names; // 傳達(dá)室的花名冊(cè)
            };
            int main()
            {
            // 學(xué)校的學(xué)生
            map<string,shared_ptr<human>> humans;
            humans["Jiawei"] = make_shared<human>("Jiawei");
            humans["Chen"] = make_shared<human>("Chen");
            humans["Xibei"] = make_shared<human>("Xibei");

            // 傳達(dá)室,根據(jù)學(xué)生構(gòu)造一個(gè)花名冊(cè)
            doorman dm(humans);
            // 有人找Chen
            dm.call("Chen");
            // 有人找Fu
            dm.call("Fu");

            // Chen離開(kāi)學(xué)校,對(duì)象被析構(gòu)
            humans.erase("Chen");
            // 又有人打來(lái)電話找Chen,這時(shí)他已經(jīng)不在學(xué)校,只能給他留一個(gè)消息了
            dm.call("Chen");
            // 有人找Jiawei,她還在學(xué)校呢,直接叫她
            dm.call("Jiawei");

            return 0;
            }
            從這段程序的輸出,我們也可以看出,我們?cè)趧h除humans容器中的Chen這個(gè)元素是,對(duì)應(yīng)的human對(duì)象也被析構(gòu),doorman中指向這個(gè)對(duì)象的weak_ptr并不影響它的析構(gòu),當(dāng)我們?cè)俅螄L試訪問(wèn)這個(gè)對(duì)象時(shí)候,lock()無(wú)法成功獲得與之關(guān)聯(lián)的shared_ptr,也就無(wú)法對(duì)其進(jìn)行訪問(wèn)了。

            Chen was called.
            Fu is not in the school.
            Chen was destructed.
            Chen has left school.I will leave a message for him.
            Jiawei was called.
            Xibei was destructed.
            Jiawei was destructed.

            這里大家可能會(huì)問(wèn),為什么不在doorman中使用裸指針呢?。。。

            那么,為什么不直接使用shared_ptr呢? 參考原文。

            總結(jié)起來(lái),weak_ptr用于訪問(wèn)了那些不具備所有權(quán)的,可能存在也可能不存在的對(duì)象。

            posted on 2011-09-20 16:29 陳良喬——《我的第一本C++書(shū)》 閱讀(1798) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久99热只有频精品8| 久久国产精品一国产精品金尊| 国产成人精品久久亚洲高清不卡| 99久久精品免费观看国产| 精品久久久久久无码中文字幕| 一级女性全黄久久生活片免费| 99久久精品免费看国产一区二区三区| 精品久久久无码人妻中文字幕豆芽| 99久久精品免费看国产| 亚洲αv久久久噜噜噜噜噜| 精品久久国产一区二区三区香蕉| AV无码久久久久不卡蜜桃| 久久精品99无色码中文字幕| 久久香蕉超碰97国产精品| 中文成人无码精品久久久不卡| 久久96国产精品久久久| 99精品久久精品一区二区| 久久久久国产一区二区| 欧洲成人午夜精品无码区久久| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 99国内精品久久久久久久| 国产偷久久久精品专区| 色婷婷狠狠久久综合五月| 亚洲一本综合久久| 久久99精品久久久久久久久久| 久久久国产精华液| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 18禁黄久久久AAA片| 热综合一本伊人久久精品| 精品久久久久久久久久久久久久久| 99久久无码一区人妻a黑| 色综合久久无码五十路人妻| 狠狠色婷婷久久综合频道日韩 | 国产69精品久久久久9999| 国产精品久久久久久福利69堂| 中文字幕久久精品无码| 99蜜桃臀久久久欧美精品网站| 国产成年无码久久久免费| 久久综合亚洲欧美成人| 99久久久精品免费观看国产| 久久久久久久尹人综合网亚洲 |