• <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>
            posts - 297,  comments - 15,  trackbacks - 0
            使用情景:當(dāng)類對象被 shared_ptr 管理時,需要在類自己定義的函數(shù)里把當(dāng)前類對象作為參數(shù)傳給其他函數(shù)時,這時需要傳遞一個 shared_ptr ,否則就不能保持 shared_ptr 管理這個類對象的語義(因為有一個 raw pointer 指向這個類對象,而 shared_ptr 對類對象的這個引用沒有計數(shù),很有可能 shared_ptr 已經(jīng)把類對象資源釋放了,而那個調(diào)用函數(shù)還在使用類對象——顯然,這肯定會產(chǎn)生錯誤)。
            很好奇這個模板類的實現(xiàn)。
            先看看怎么使用:
            對一個類 A ,當(dāng)我們希望使用 shared_ptr 來管理其類對象時,而且需要在自己定義的函數(shù)里把類對象 shared_ptr (為什么不用普通指針,當(dāng)我們使用智能指針管理資源時,必須統(tǒng)一使用智能指針,而不能在某些地方使用智能指針某些地方使用 raw pointer ,否則不能保持智能指針的語義,從而產(chǎn)生各種錯誤)傳給其他函數(shù)時,可以讓類 A 從 enable_shared_from_this 繼承:
            class A : public boost::enable_shared_from_this<A> {
            };
            然后在類 A 中需要傳遞類對象本身 shared_ptr 的地方使用 shared_from_this 函數(shù)來獲得指向自身的 shared_ptr 。
            一個非常有代表性的例子:
            另《Beyond the C++ Standard Library》 shared_ptr 節(jié)也有很簡單明了的例子。
            實現(xiàn)原理:
            首先要考慮的是:在類對象本身當(dāng)中不能存儲類對象本身的 shared_ptr ,否則類對象 shared_ptr 永遠也不會為0了,從而這些資源永遠不會釋放,除非程序結(jié)束。
            其次:類對象肯定是外部函數(shù)通過某種機制分配的,而且一經(jīng)分配立即交給 shared_ptr 管理(再次強調(diào)一遍:給 shared_ptr 管理的資源必須在分配時交給 shared_ptr ),而且以后凡是需要共享使用類對象的地方必須使用這個 shared_ptr 當(dāng)作右值來構(gòu)造產(chǎn)生或者拷貝產(chǎn)生另一個 shared_ptr 從而達到共享使用的目的。
            有了以上兩點的限制,要實現(xiàn)我們的目標(biāo)(即在類對象內(nèi)部使用類對象的 shared_ptr )有以下兩種方案:
            1、類對象的外部 shared_ptr 作為函數(shù)參數(shù)傳給類的需要引用類對象自身的函數(shù)——顯然,這種方法很丑陋,而且并不是所有的情況都可行(如在外部 shared_ptr 不可見的作用域中就不行);
            2、類對象自身存儲某種信息,在需要自身 shared_ptr 時來產(chǎn)生一個臨時的 shared_ptr 。
            顯然,第2種方法更優(yōu)雅(對于用戶來說),關(guān)鍵是信息怎么存儲?
            對了, weak_ptr !
            實際上, boost 中就是這樣實現(xiàn)的。
            但現(xiàn)在的問題是:何時初始化這個 weak_ptr ?因為類對象生成時還沒有生成相應(yīng)的用來管理這個對象的 shared_ptr 。
            boost 1.39.0 中是這樣實現(xiàn)的:
            首先生成類 A :會依次調(diào)用 enable_shared_from_this 的構(gòu)造函數(shù)(定義為 protected ),以及類 A 的構(gòu)造函數(shù)。在調(diào)用 enable_shared_from_this 的構(gòu)造函數(shù)時,會初始化定義在 enable_shared_from_this 中的 weak_ptr (調(diào)用其默認(rèn)構(gòu)造函數(shù)),這時這個 weak_ptr 是無效的(或者說不指向任何對象)。
            接著:外部程序會把指向類 A 對象的指針作為初始化參數(shù)來初始化一個 shared_ptr 。
            現(xiàn)在來看看 shared_ptr 是如何初始化的, shared_ptr 定義了如下構(gòu)造函數(shù):
            template<class Y>
                explicit shared_ptr( Y * p ): px( p ), pn( p ) 
                {
                    boost::detail::sp_enable_shared_from_this( this, p, p );
                }
            里面調(diào)用了  boost::detail::sp_enable_shared_from_this :
            template< class X, class Y, class T >
             inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx,
             Y const * py, boost::enable_shared_from_this< T > const * pe )
            {
                if( pe != 0 )
                {
                    pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
                }
            }
            里面又調(diào)用了 enable_shared_from_this 的 _internal_accept_owner :
            template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
                {
                    if( weak_this_.expired() )
                    {
                        weak_this_ = shared_ptr<T>( *ppx, py );
                    }
                }
            而在這里對 enable_shared_from_this 的成員 weak_ptr 進行拷貝賦值,使得整個 weak_ptr 作為類對象  shared_ptr 的一個觀察者。
            這時,當(dāng)類對象本身需要自身的 shared_ptr 時,就可以從這個 weak_ptr 來生成一個了。
            posted on 2012-05-20 15:37 chatler 閱讀(617) 評論(0)  編輯 收藏 引用 所屬分類: GP_STL
            <2010年8月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個博客還是不錯,雖然做的東西和我不大相關(guān),覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            亚洲伊人久久大香线蕉综合图片 | 久久精品国产亚洲AV蜜臀色欲| 四虎影视久久久免费观看| 一本色道久久HEZYO无码| 色综合久久精品中文字幕首页| 欧美成a人片免费看久久| 久久精品国产亚洲AV蜜臀色欲| 日韩一区二区久久久久久| 久久久久久伊人高潮影院| 久久99国产精品二区不卡| 久久受www免费人成_看片中文| 69SEX久久精品国产麻豆| 亚洲国产成人精品91久久久| 俺来也俺去啦久久综合网| 久久久久久午夜精品| 国内精品久久久久久久coent| 日产精品久久久一区二区| 久久国产精品波多野结衣AV | 久久天天躁狠狠躁夜夜不卡| 无码国内精品久久人妻蜜桃| 久久精品国产精品亚洲下载| 精品久久久久久久久午夜福利| 怡红院日本一道日本久久 | 国产巨作麻豆欧美亚洲综合久久 | 国产V亚洲V天堂无码久久久| 久久天天婷婷五月俺也去| 久久久久国产日韩精品网站| 伊人色综合久久天天| 狠狠狠色丁香婷婷综合久久五月| 性高湖久久久久久久久AAAAA| 狠色狠色狠狠色综合久久| 久久er99热精品一区二区| 日韩乱码人妻无码中文字幕久久 | 欧美一区二区精品久久| 国产一久久香蕉国产线看观看| 久久精品国产清自在天天线| 久久午夜福利无码1000合集| 欧美亚洲另类久久综合婷婷 | 亚洲天堂久久精品| 情人伊人久久综合亚洲| 久久精品成人欧美大片|