• <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>
            1.Do you Smart Pointer?

            ????? Smart Pointer,中文名:智能指針, 舶來品?
            ????? 不可否認,資源泄露(resource leak)曾經是C++程序的一大噩夢.垃圾回收
            ????? 機制(Garbage Collection)一時頗受注目.然而垃圾自動回收機制并不能
            ????? 滿足內存管理的即時性和可視性,往往使高傲的程序設計者感到不自在.
            ????? 況且,C++實現沒有引入這種機制.在探索中,C++程序員創造了鋒利的
            ????? "Smart Pointer".一定程度上,解決了資源泄露問題.

            ????? 也許,經常的,你會寫這樣的代碼:
            ????? //x擬為class:

            //??class?x{
            ??????
            //????????????public:????????
            ??????
            //???????????????????int?m_Idata;
            ??????
            //????????????public:
            ??????
            //???????????????????x(int?m_PARAMin):m_Idata(m_PARAMin){}
            ??????
            //???????????????????void?print(){?cout<<m_Idata<<endl;?}
            ??????
            //????????????.....
            ??????
            //????????????}
            ??????
            //
            ??????void?fook(){
            ??????x
            *?m_PTRx?=?new?A(m_PARAMin);
            ??????m_PTRx
            ->DoSomething();?????//#2
            ??????delete?m_PTRx;
            ??????}


            ??????????? 是的,這里可能沒什么問題.可在復雜、N行、m_PTRclassobj所指對象生命周
            ????? 期要求較長的情況下,你能保證你不會忘記delete m_PTRclassobj嗎?生活中,
            ????? 我們往往不應該有太多的口頭保證,我們需要做些真正有用的東西.還有一個
            ????? 更敏感的問題:異常.假如在#2方法執行期異常發生,函數執行終止,那么new
            ????? 出的對象就會泄露.于是,你可能會說:那么就捕獲異常來保證安全性好了.
            ????? 你寫這樣的程式:

            ????void?fook(){
            ??????A
            *?m_PTRx?=?new?x(m_PARAMin);
            ??????
            try{
            ??????????m_PTRx
            ->DoSomething();
            ??????}

            ??????
            catch(..){
            ??????????delete?m_PTRx;
            ??????????
            throw;
            ??????}

            ??????delete?m_PTRx;
            ??????}

            ????? 哦!天哪!想象一下,你的系統,是否會象專為捕獲異常而設計的.

            ????? 一天,有人給你建議:"用Smart Pointer,那很安全.".你可以這樣重寫你的程序:
            ???

            ??????void?fook(){
            ??????auto_ptr
            <x>?m_SMPTRx(new?x(m_PARAMin));
            ??????m_SMPTRx
            ->DoSomething();
            ??????}

            ?

            ????? OK!你不太相信.不用delete嗎?
            ????? 是的.不用整天提心吊膽的問自己:"我全部delete了嗎?",而且比你的delete
            ????? 策略更安全.

            ????? 然后,還有人告訴你,可以這樣用呢:

            ?

            ?ok1.
            ??????auto_ptr
            <x>?m_SMPTR1(new?x(m_PARAMin));?
            ??????auto_ptr
            <x>?m_SMPTR2(m_SMPTR1);??//#2
            ??????May?be?you?can?code?#2?like?this?:
            ??????????auto_ptr
            <x>?m_SMPTR2;
            ??????????m_SMPTR2?
            =?m_SMPTR1;??????
            ??????ok2.
            ??????auto_ptr
            <int>?m_SMPTR1(new?int(32));
            ??????
            ??????ok3.
            ??????auto_ptr
            <int>?m_SMPTR1;
            ??????m_SMPTR1?
            =?auto_ptr<int>(new?int(100));
            ??????也可以:
            ??????auto_ptr
            <int>?m_SMPTR1(auto_ptr<int>(new?int(100)));
            ??????
            ??????ok4.
            ??????auto_ptr
            <x>?m_SMPTR1(new?x(m_PARAMin));
            ??????m_SMPTR1.reset(
            new?x(m_PARAMin1));
            ??????
            ??????ok5.
            ??????auto_ptr
            <x>?m_SMPTR1(new?x(m_PARAMin));
            ??????auto_ptr
            <x>?m_SMPTR2(m_SMPTR.release());
            ??????cout
            <<(*m_SMPTR2).m_Idata<<endl;??
            ??????
            ??????ok6.
            ??????auto_ptr
            <int>?fook(){
            ??????
            return?auto<int>(new?int(100));
            ??????}

            ?


            ?????????? ok7.............and so on
            ?????
            ????? 但不可這樣用:
            ??????
            ??????

            no1.???
            ??????
            char*?chrarray?=?new?char[100];
            ??????strcpy(chrarray,
            "I?am?programming.");
            ??????auto_ptr
            <char*>?m_SMPTRchrptr(chrarray);
            ??????
            //auto_ptr并不可幫你管理數組資源?????
            ???????
            ??????no2.
            ??????vector
            <auto_ptr<x>>?m_VECsmptr;
            ??????m_VECsmptr.push_back(auto_ptr
            <int>(new?int(100)));
            ??????
            //auto_ptr并不適合STL內容.
            ???????
            ??????no3.
            ??????
            const?auto_ptr<x>?m_SMPTR1(new?x(100));
            ??????auto_ptr
            <x>?m_SMPTR(new?x(200));
            ??????
            ??????no4.
            ??????x?m_OBJx(
            300);
            ??????auto_ptr
            <x>?m_SMPTR(&m_OBJx);
            ??????
            ??????no5
            ??????x
            *?m_PTR?=?new?x(100);
            ??????auto_ptr
            <x>?m_SMPTR?=?m_pTR;
            ??????


            ????? no6..........and so on

            ????? 預先提及所有權的問題,以便下面帶著疑問剖析代碼?

            ?

            ??????power1.
            ??????auto_ptr
            <x>?m_SMPTR1(new?x(100));
            ??????auto_ptr
            <x>?m_SMPTR2?=?m_SMPTR1;
            ??????m_SMPTR2
            ->print();
            ??????
            //輸出:100.
            ??????m_SMPTR1->print();
            ??????
            //!!?非法的.

            ??????power2.
            ??????auto_ptr
            <x>?m_SMPTR(new?x(100));
            ??????
            ??????auto_ptr
            <x>?returnfun(auto_ptr<x>?m_SMPTRin){
            ??????
            return?m_SMPTRin;
            ??????}

            ??????
            ??????auto_ptr
            <x>?=?returnfun(m_SMPTR);??//#5

            ?

            ????? //在上面的#5中,我要告訴你對象所有權轉移了兩次.
            ????? //什么叫對象所有權呢?
            ??
            ??? 2. std::auto_ptr的設計原理
            ??????
            ????? 上面的一片正確用法,它們在干些什么?
            ??????????? 一片非法,它們犯了什么罪?
            ??????????? 一片什么所有權轉移,它的內部機智是什么?
            ????? 哦!一頭霧水?下面我們就來剖析其實現機制.
            ????? 基礎知識:
            ????????????? a.智能指針的關鍵技術:在于構造棧上對象的生命期控制
            ??????????????? 堆上構造的對象的生命期.因為在智能指針的內部,存儲
            ??????????????? 著堆對象的指針,而且在構析函數中調用delete行為.
            ??????????????? 大致機構如下:
            ??????????????? x* m_PTRx = new x(100);//#1
            ??????????????? template<typename T>
            ??????????????? auto_ptr{
            ??????????????? private:
            ??????????????? T* m_PTR;//維護指向堆對象的指針,在auto_ptr定位后????
            ??????????????? ....???? //它應該指向#1構造的對象,即擁有所有權.
            ??????????????? ~auto(){ delete m_PTR; }
            ??????????????? ....
            ??????????????? }
            ???????????? b.所有權轉移之說
            ?????????????? 上面曾有一非法的程式片段如下:
            ?????????????? auto_ptr<x> m_SMPTR1(new x(100));
            ?????????????? auto_ptr<x> m_SMPTR2 = m_SMPTR1;
            ?????????????? m_SMPTR2->print();
            ?????????????? //輸出:100.
            ?????????????? m_SMPTR1->print();
            ?????????????? //!! 非法的.
            ?????????????? 按常理來說,m_SMPTR->print();怎么是非法的呢?
            ?????????????? 那是因為本來,m_SMPTR1維護指向new x(100)的指針,
            ?????????????? 可是m_SMPTR2 = m_SMPTR1;auto_ptr內部機制使得m_SMPTR1將對象的地址
            ?????????????? 傳給m_SMPTR2,而將自己的對象指針置為0.
            ?????????????? 那么自然m_SMPTR->print();失敗.
            ?????????????? 這里程序設計者要負明顯的職責的.
            ?????????????? 那么auto_ptr為什么采取這樣的策略:保證所有權的單一性.
            ?????????????????????????????????????????????? 亦保證了系統安全性.
            ?????????????? 如果多個有全權的auto_ptr維護一個對象,那么在你消除一個
            ?????????????? auto_ptr時,將導致多個auto_ptr的潛在危險.
            ?????
            ?????? 下面我們以SGI-STL的auto_ptr設計為樣本(去掉了無關分析的宏),來剖析其原理.

            ?

            #1??template?<class?_Tp>?class?auto_ptr?{
            ???????#
            2??private:
            ???????#
            3??_Tp*?_M_ptr;??//定義將維護堆對象的指針

            ???????#
            4??public:
            ???????#
            5??typedef?_Tp?element_type;??//相關類型定義
            ???????#6??explicit?auto_ptr(_Tp*?__p?=?0)?__STL_NOTHROW?:?_M_ptr(__p)?{}
            ???????#
            7??auto_ptr(auto_ptr&?__a)?__STL_NOTHROW?:?_M_ptr(__a.release())?{}
            ???????#
            8??template?<class?_Tp1>?auto_ptr(auto_ptr<_Tp1>&?__a)?__STL_NOTHROW
            ?????????????????????????????????????????????????:?_M_ptr(__a.release())?
            {}
            ???????????
            //#6、#7、#8是auto_ptr構造函數的三個版本.
            ???????????
            //#6注釋:傳入對象的指針,構造auto_ptr.explicit關鍵字:禁止隱式轉換.
            ???????????
            //????????這就是ok2正確,而no5(隱式轉換)錯誤的原因.
            ???????????
            //#7注釋:拷貝構造函數.
            ???????????
            //????????傳入auto_ptr實例,構造auto_ptr.?ok1、ok3使用了這個構造式.
            ???????????
            //????????它是一個很關鍵的構造函數,在具體情況下,我們再分析
            ???????????
            //#8注釋:auto_ptr的模板成員,可在繼承對象重載的基礎上,實現特殊功能.
            ???????????
            //???
            ???????????
            //???舉例:
            ???????????
            //???class?A{?public:?
            ???????????
            //??????????virtual?void?fook(){cout<<"I?am?programming"<<endl;
            ???????????
            //??????????/*..........*/???????????????????????????????????};?
            ???????????
            //???class?B?:?public?A?{
            ???????????
            //??????????virtual?void?fook(){?cout<<"I?am?working"<<endl;
            ???????????
            //?????????/*...........*/??????????????????????????????????};??
            ???????????
            //???auto_ptr<A>?m_SMPTRa(new?A(33));//實質:
            ???????????
            //???auto_ptr<B>?m_SMPTRb(m_SMPTRa);?//基類的指針可以賦給派生類的指針??????????
            ???????????
            //??????????????
            ???????????
            //???auto_ptr<B>?m_SMPTRb(new?B(44));//實質:
            ???????????
            //???auto_ptr<A>?m_SMPTRa(m_SMPTRb);?//派生類的指針不可賦給基類的指針
            ???????????
            //???????
            ???????????
            //???auto_ptr<A>?m_SMPTRa(new?B(33));??//?ok!??
            ???????????
            //???m_SMPTRa->fook()將調用派生類B的fook()
            ???????????
            //???m_SMPTRa->A::fook()將調用基類A的fook()
            ???????????
            //????
            ???????????
            //???auto_ptr<B>?m_SMPTRb(new?A(33));??//?wrong!
            ???????????
            //???
            ???????????
            //???
            ???????#9??auto_ptr&?operator=(auto_ptr&?__a)?__STL_NOTHROW?{
            ???????#
            10?if?(&__a?!=?this)?{?delete?_M_ptr;??_M_ptr?=?__a.release();?}
            ???????#
            11?return?*this;
            ???????#
            12?}

            ?????????
            ???????#
            13?template?<class?_Tp1>
            ???????#
            14?auto_ptr&?operator=(auto_ptr<_Tp1>&?__a)?__STL_NOTHROW?{
            ???????#
            15?if?(__a.get()?!=?this->get())?{?delete?_M_ptr;?_M_ptr?=?__a.release();?}
            ???????#
            16?return?*this;
            ???????#
            16?}
            ??
            ??????????
            //
            ??????????
            //?#9~~#16?兩個版本的指派函數.
            ??????????
            //?????????delete?_M_ptr;?在指派前,銷毀原維護的對象.
            ??????????
            //?????????_a.release()?;?release操作,詳細代碼參見#20~~#23.
            ??????????
            //????????????????????????用于*this獲得被指派對象,
            ??????????
            //????????????????????????且將原維護auto_ptr置空.
            ??????????
            //?????no3使用了第一種指派.
            ??????????
            //?????而權限轉移正是_a.release()的結果.
            ??????????
            ???????#
            17?~auto_ptr()?__STL_NOTHROW?{?delete?_M_ptr;?}
            ??????????
            //構析函數.消除對象.注意這里對對象的要求!
            ??????????
            ???????#
            17?_Tp&?operator*()?const?__STL_NOTHROW?{??return?*_M_ptr;?}
            ???????#
            18?_Tp*?operator->()?const?__STL_NOTHROW?{?return?_M_ptr;??}
            ???????#
            19?_Tp*?get()?const?__STL_NOTHROW?{?return?_M_ptr;?}
            ?????????
            //
            ?????????
            //??操作符重載.
            ?????????
            //?#17注釋:提領操作(dereference),獲得對象.?見ok5用法.
            ?????????
            //?#18注釋:成員運算符重載,返回對象指針.
            ?????????
            //?#19注釋:普通成員函數.作用同于重載->運算符
            ?????????
            //
            ???????#20?_Tp*?release()?__STL_NOTHROW?{
            ???????#
            21?_Tp*?__tmp?=?_M_ptr;
            ???????#
            22?_M_ptr?=?0;
            ???????#
            23?return?__tmp;????????????????}

            ?????????
            //上面已經詳解??????
            ?
            ???????#
            24?void?reset(_Tp*?__p?=?0)?__STL_NOTHROW?{
            ???????#
            25?delete?_M_ptr;
            ???????#
            26?_M_ptr?=?__p;??????????????????????????}

            ?????????
            //
            ?????????
            //傳入對象指針,改變auto_ptr維護的對象
            ?????????
            //???????且迫使auto_ptr消除原來維護的對象
            ?????????
            //???????見ok3用法.

            ?????????
            //?According?to?the?C++?standard,?these?conversions?are?required.??Most
            ?????????
            //?present-day?compilers,?however,?do?not?enforce?that?requirement---and,?
            ?????????
            //?in?fact,?most?present-day?compilers?do?not?support?the?language?
            ?????????
            //?features?that?these?conversions?rely?on.
            ?????????


            ??????????????? //下面這片段用于類型轉化,目前沒有任何編譯器支持
            ???????? //具體技術細節不訴.?????????

            ?

            ?????????

            #ifdef?__SGI_STL_USE_AUTO_PTR_CONVERSIONS

            ??????#
            27?private:
            ??????#
            28?template<class?_Tp1>?
            ??????#
            29?struct?auto_ptr_ref?{?_Tp1*?_M_ptr;?auto_ptr_ref(_Tp1*?__p)?:?_M_ptr(__p)?{}
            ?????????????????????????????}
            ;

            ??????#
            30?public:
            ??????#
            31?auto_ptr(auto_ptr_ref<_Tp>?__ref)?__STL_NOTHROW
            ???????????????????????????????:?_M_ptr(__ref._M_ptr)?
            {}
            ??????#
            32?template?<class?_Tp1>?
            ??????#
            33?operator?auto_ptr_ref<_Tp1>()?__STL_NOTHROW?
            ??????#
            34?{?return?auto_ptr_ref<_Tp>(this->release());?}
            ??????#
            35?template?<class?_Tp1>?operator?auto_ptr<_Tp1>()?__STL_NOTHROW
            ??????#
            36?{?return?auto_ptr<_Tp1>(this->release());?}
            ??????#
            37?#endif?/*?__SGI_STL_USE_AUTO_PTR_CONVERSIONS?*/
            ??????#
            38?};

            ??????
            ????? OK!就是這樣了.
            ????? 正如上面原理介紹處敘說,
            ????? 你需要正視兩大特性:
            ????? 1.構造棧對象的生命期控制堆上構造的對象的生命期
            ????? 2.通過release來保證auto_ptr對對象的獨權.
            ?????
            ???? 在我們對源碼分析的基礎上,重點看看:
            ???? no系列錯誤在何處?
            ???? no1.
            ???????? 我們看到構析函數template<class _Tp>
            ???????????????????????? ~auto_ptr() _STL_NOTHROW
            ??????????????????????? { delete _M_ptr; }
            ???????? 所以它不能維護數組,
            ???????? 維護數組需要操作:delete[] _M_ptr;
            ???? no2.
            ??????? 先提部分vector和auto_ptr代碼:
            ??????? a.提auto_ptr代碼
            ??????????
            ????????

            auto_ptr(auto_ptr&?__a)?__STL_NOTHROW?:?_M_ptr(__a.release())?{}

            ????????
            ??????? b.提vector代碼
            ?????????


            ??????????Part1:
            ??????????
            void?push_back(const?_Tp&?__x)?{
            ??????????
            if?(_M_finish?!=?_M_end_of_storage)?{
            ??????????construct(_M_finish,?__x);
            ??????????
            ++_M_finish;
            ??????????}

            ??????????
            else
            ?????????_M_insert_aux(end(),?__x);
            ??????????}

            ????????
            ?????????Part2:
            ?????????template?
            <class?_T1,?class?_T2>
            ?????????inline?
            void?construct(_T1*?__p,

            ?????????
            //++++++++++++++++++++++++++++++++?
            ?????????
            //?????????const?_T2&?__value)?{?+
            ?????????
            //++++++++++++++++++++++++++++++++
            ?????????
            //??new?(__p)?_T1(__value);??????+
            ?????????
            //++++++++++++++++++++++++++++++++

            ?????????}
            ?????????
            ?????????Part3.
            ?????????template?
            <class?_Tp,?class?_Alloc>
            ?????????
            void?
            ?????????vector
            <_Tp,?_Alloc>::_M_insert_aux
            ?????????(iterator?__position,

            ??????????
            //++++++++++++++++++++++++++++++++?
            ??????????
            //????????const?_Tp&?__x)???????++
            ??????????
            //++++++++++++++++++++++++++++++++???
            ?
            ?????????
            {
            ?????????
            if?(_M_finish?!=?_M_end_of_storage)?{
            ?????????construct(_M_finish,?
            *(_M_finish?-?1));
            ?????????
            ++_M_finish;

            ?????????
            //++++++++++++++++++++++++++++++++
            ?????????
            //?????_Tp?__x_copy?=?__x;???????+
            ?????????
            //++++++++++++++++++++++++++++++++

            ?????????copy_backward(__position,?_M_finish?
            -?2,?_M_finish?-?1);
            ?????????
            *__position?=?__x_copy;
            ?????????}

            ?????????
            else?{
            ?????????
            const?size_type?__old_size?=?size();
            ?????????
            const?size_type?__len?=?__old_size?!=?0???2?*?__old_size?:?1;
            ?????????iterator?__new_start?
            =?_M_allocate(__len);
            ?????????iterator?__new_finish?
            =?__new_start;
            ?????????__STL_TRY?
            {
            ?????????__new_finish?
            =?uninitialized_copy
            ?????????(_M_start,?__position,?__new_start);
            ?????????construct(__new_finish,?__x);
            ?????????
            ++__new_finish;
            ?????????__new_finish?
            =?uninitialized_copy
            ????????(__position,?_M_finish,?__new_finish);
            ????????}

            ????????__STL_UNWIND((destroy(__new_start,__new_finish),?
            ??????????????????_M_deallocate(__new_start,__len)));
            ???????destroy(begin(),?end());
            ???????_M_deallocate(_M_start,?_M_end_of_storage?
            -?_M_start);
            ???????_M_start?
            =?__new_start;
            ???????_M_finish?
            =?__new_finish;
            ???????_M_end_of_storage?
            =?__new_start?+?__len;
            ???????}

            ???????}

            ?

            ?????? 從提取的vector代碼,Part1可看出,push_back的操作行為.
            ?????? 兵分兩路,可是再向下看,你會發現,無一例外,都
            ?????? 通過const _Tp& 進行拷貝行為,那么從auto_ptr提出的片段就
            ?????? 派上用場了.
            ?????? 可你知道的,auto_ptr總是堅持對對象的獨權.那必須修改
            ?????? 原來維護的對象,而vector行為要求const _Tp&,這樣自然會產生
            ?????? 問題.一般編譯器是可以發覺這種錯誤的.

            ?????? 其實,STL所有的容器類都采用const _Tp&策略.
            ?
            ?????? //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            ????? + 看了sutter和Josuttis的兩篇文章中,都提及:??????????????????? +
            ????? + STL容器不支持auto_ptr原因在于copy的對象只是獲得所有權的對象, +
            ????? + 這種對象不符合STL的要求.可是本人總感覺即時不是真正的復制對象,+
            ????? + 但我用vector<auto_ptr<x> >的目的就在于維護對象,并不在乎????? +
            ????? + 所謂的完全對象.而且我用自己寫的Smart Pointer配合STL容器工作, +
            ????? + 很正常.那需要注意的僅僅是const問題.????????????????????????? +
            ????? +????????????????????????????????????????????????????????????? +
            ????? //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

            ???? no3.
            ??????? 這個也是auto_ptr隱含的所有權問題引起的.
            ??????? const auto_ptr不允許修改.
            ??????? 隨便提及:const對象不代表對象一點不可以改變.
            ????????????????? 在兩種const語義下,都有方法修改對象或對象內部指針維護的對象
            ???????????????? 或其它資源.
            ???? no4.
            ??????? 再看auto_ptr的構析函數.
            ??????? delete不可以消除棧上資源.

            ???? no5.
            ??????? 依賴傳入對象指針的構造函數被聲明為explicit,禁止隱式轉換.

            ???
            ??? 3.auto_ptr高級使用指南
            ?????
            ????? a.類成員auto_ptr,禁止構造函數以構建"完全對象"

            ?

            Programme1:
            ????????
            struct?Structx{
            ???????????????
            int?m_Idata;
            ???????????????
            char?m_CHRdata;
            ???????????????
            /*?and?so?on?*/
            ????????}
            ;
            ????????出于對象編程的理念,
            ????????我們將Structx打造成包裹類:
            ????????
            class?StructWrapper{
            ????????
            private:
            ????????Structx
            *?m_STRTxptr;
            ????????
            public:
            ????????StructWrapper():m_STRTxptr(
            new?Structx){}
            ????????
            ~StructWrapper(){delete?m_SMRTxptr;?}
            ????????
            public:
            ????????
            void?Soperator1(){?/*?針對Structx對象的特性操作?*/}
            ????????
            void?Soperator2(){?/*?針對Structx對象的特性操作?*/}????????
            ????????
            /*??and?so?on?*/
            ????????}
            ;?
            ????????
            ????????Programme2:
            ????????
            class?StructWrapper{
            ????????
            private:
            ????????auto_ptr
            <Structx>?m_SMPTRx;
            ????????
            public:
            ????????StructWrapper():m_SMPTRAx(
            new?Structx){}
            ????????
            public:
            ????????
            void?Soperator1(){?/*?針對Structx對象的特性操作?*/}
            ????????
            void?Soperator2(){?/*?針對Structx對象的特性操作?*/}????????
            ????????
            /*??and?so?on?*/
            ????????}
            ;?
            ????????
            ????????Programme3:
            ????????StructWrapper::StructWrapper(
            const?StructWrapper&?other)
            ????????:?M_SMPTRx(
            new?Struct(*other.m_SMPTRx))?{?}
            ????????StructWrapper
            &?StructWrapper::operator=(const?StructWrapper?&other){
            ????????
            *m_SMPTRx?=?*other.m_SMPTRx;
            ????????}
            ;


            ??????????????? 處于對構建于堆中的對象(new Structx)智能維護的需要.
            ??????? 我們將programme1改造為programme2:
            ??????? 不錯,對象是可以智能維護了.
            ??????? 對于包裹類(StructWrapper)你是否會有這樣的構造或指派操作:
            ???????? StructWrapper m_SMPTRWrapper2(m_SMPTRWrapper1);
            ??????
            ???????? StructWrapper mSMPTRWrapper2 = m_SMPTRWrapper1;
            ???????? 那么請注意:
            ???????? 當你坦然的來一個:M_SMPTRWrapper1->Soperator1();的時候,
            ???????? 系統崩潰了.
            ???????? 不必驚訝,所有權還是所有權問題.
            ???????? 問一下自己:當programme2默認拷貝構造函數作用時,又調用了auto_ptr的
            ???????? 默認構造函數,那么auto_ptr所有的默認行為都遵循獨權策略.對,就這樣.
            ???????? m_SMPTRWrapper1的對象所有權轉移給了m_SMPTRWrapper2.
            ???????? M_SMPTRWrapper1->Soperator1();那么操作變成了在NULL上的.
            ???????? 哦!系統不崩潰才怪.
            ???????? 那么你需要想,programme3那樣利用auto_ptr的提領操作符自己的
            ???????? 構造"完全對象".

            ?????? b.利用const關鍵字,防止不經意的權限轉移
            ????????
            ???????? 從上面的敘述,你可看出,所有權轉移到處可以釀成大禍.
            ???????? 而對于一般應用來說,獨權又是很好的安全性策略.
            ???????? 那么我們就用const來修飾auto_ptr,禁止不經意的錯誤.
            ???????
            ???????? 當然上面提及:并不代表auto_ptr是不可修改的.
            ???????? 處于需要,從兩種const語義,你都可實現修改.

            ???????? 然,你還希望在函數傳入傳出auto_ptr那么你可傳遞auto_ptr的引用,
            ???????? 那就萬無一失了: void fook(const auto_ptr<x>& m_PARAMin);
            ???????? 在返回后賦予其它時,使用引用是不行的.你得用指針.
            ???????? 因為引用無論作為lvalue還是rvaluev,都會調用構造或指派函數.


            ??? 4.你是否覺得std::auto_ptr還不夠完美
            ?????
            ????? 在實踐中,std::auto_ptr能滿足你的需求嗎???????????
            ?
            ????? Andrei Alexandrescu在一篇文章中,提及:有關Smart Pointer的技術就像
            ????? 巫術.Smart Pointer作為C++垃圾回收機制的核心,它必須足夠強大的、具有工業強度和安全性.
            ????? 但為了可一勞永逸我們還需要披荊斬棘繼續探索.

            ????? 下面在需求層面上,我們思索一下我們的智能指針還需要些什么?
            ?
            ??????? a. std::auto_ptr 能夠處理數組嗎?我們可以用智能指針來管理其它的資源嗎?
            ?????????? 譬如一個線程句柄、一個文件句柄 and so on !
            ??????? b. 對于我們的對象真的永遠實行獨權政策嗎?
            ??????? c. Our 智能指針還需要在繼承和虛擬層面上發揮威力 !
            ??????? d. 往往,需要擴展Our 智能指針的功能成員函數來滿足動態的需要 !
            ??????? e. 也許,你需要的還很多.

            posted on 2006-12-15 17:35 清源游民 閱讀(7878) 評論(7)  編輯 收藏 引用 所屬分類: C++

            FeedBack:
            # re: (轉)剖析C++標準庫智能指針(std::auto_ptr)
            2009-03-25 12:58 | yuzx
            挺不錯  回復  更多評論
              
            # re: (轉)剖析C++標準庫智能指針(std::auto_ptr)
            2010-05-31 15:37 | lxs
            很好,很強大,學習了  回復  更多評論
              
            # re: (轉)剖析C++標準庫智能指針(std::auto_ptr)
            2011-11-10 13:54 | 一個喜歡葫蘆的boy
            very very nice!  回復  更多評論
              
            # re: (轉)剖析C++標準庫智能指針(std::auto_ptr)
            2011-11-10 13:54 | 一個喜歡葫蘆的boy
            double nice!  回復  更多評論
              
            # re: (轉)剖析C++標準庫智能指針(std::auto_ptr)
            2012-03-19 13:50 | 豐富
            // auto_ptr<B> m_SMPTRb(m_SMPTRa); //基類的指針可以賦給派生類的指針
            //
            // auto_ptr<B> m_SMPTRb(new B(44));//實質:
            // auto_ptr<A> m_SMPTRa(m_SMPTRb); //派生類的指針不可賦給基類的指針

            明顯錯了  回復  更多評論
              
            # re: (轉)剖析C++標準庫智能指針(std::auto_ptr)
            2012-05-30 11:25 | tongy0
            寫的很好。收下了。  回復  更多評論
              
            # re: (轉)剖析C++標準庫智能指針(std::auto_ptr)
            2012-08-06 15:16 | hailong
            some of the contents are rather difficult for me, but i will read it laterly more seriously  回復  更多評論
              
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            留言簿(35)

            隨筆分類(78)

            隨筆檔案(74)

            文章檔案(5)

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久精品国产黑森林| 国色天香久久久久久久小说| 久久精品中文字幕有码| 亚洲国产成人久久一区久久| 久久久久久亚洲AV无码专区| 精品久久久久久久中文字幕| 久久久久久精品久久久久| 久久婷婷久久一区二区三区| 欧美成人免费观看久久| 久久A级毛片免费观看| 久久这里有精品视频| 国内精品久久久久久野外| 久久无码高潮喷水| 91久久九九无码成人网站| 久久夜色精品国产欧美乱| 久久综合一区二区无码| 久久国产精品久久久| 亚洲成色www久久网站夜月| 开心久久婷婷综合中文字幕| 久久噜噜电影你懂的| 日韩精品久久久肉伦网站| 亚洲国产成人久久综合一区77 | 久久国产高清一区二区三区| 欧美噜噜久久久XXX| 久久久久亚洲av成人网人人软件 | 国产亚洲美女精品久久久| 久久精品人人槡人妻人人玩AV| 亚洲欧美一区二区三区久久| 久久国产高清一区二区三区| 成人久久久观看免费毛片| 久久青青草原精品国产| 人妻精品久久久久中文字幕69| 国产成人精品综合久久久| 欧美黑人激情性久久| 国产美女亚洲精品久久久综合 | 99久久免费国产特黄| 久久精品国产亚洲77777| 久久99精品久久久久久久久久| 男女久久久国产一区二区三区| 精品久久久中文字幕人妻| 久久午夜羞羞影院免费观看|