• <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>
            一如技網(wǎng)
            -游戲開(kāi)發(fā)新人
            posts - 3,  comments - 3,  trackbacks - 0

            主題索引:

            一、剖析C++標(biāo)準(zhǔn)庫(kù)智能指針(std::auto_ptr)
               
                1.Do you Smart Pointer?
                2.std::auto_ptr的設(shè)計(jì)原理
                3.std::auto_ptr高級(jí)使用指南
                4.你是否覺(jué)得std::auto_ptr還不夠完美?

            二、C++條件,尋找構(gòu)造更強(qiáng)大的智能指針(Smart Pointer)的
                策略
               
                1.支持引用記數(shù)的多種設(shè)計(jì)策略
                2.支持處理多種資源
                3.支持Subclassing
                4.支持多線(xiàn)程條件下,線(xiàn)程安全的多種設(shè)計(jì)策略
                5.其它多種特殊要求下,再構(gòu)造

            三、Generic Programming基礎(chǔ)技術(shù)和Smart Pointer
                1.回首處理資源中的Traits技術(shù)
                2.回首多線(xiàn)程支持的設(shè)計(jì)


            四、COM實(shí)現(xiàn)中,Smart Pointer設(shè)計(jì)原理


            五、著名C++庫(kù)(標(biāo)準(zhǔn)和非標(biāo)準(zhǔn))中的Smart Pointer現(xiàn)狀

            ---------------------------------------------------------------------


            一、剖析C++標(biāo)準(zhǔn)庫(kù)智能指針(std::auto_ptr)
               
                1.Do you Smart Pointer?

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

                  也許,經(jīng)常的,你會(huì)寫(xiě)這樣的代碼:
                  //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;
                  }

                  是的,這里可能沒(méi)什么問(wèn)題.可在復(fù)雜、N行、m_PTRclassobj所指對(duì)象生命周
                  期要求較長(zhǎng)的情況下,你能保證你不會(huì)忘記delete m_PTRclassobj嗎?生活中,
                  我們往往不應(yīng)該有太多的口頭保證,我們需要做些真正有用的東西.還有一個(gè)
                  更敏感的問(wèn)題:異常.假如在#2方法執(zhí)行期異常發(fā)生,函數(shù)執(zhí)行終止,那么new
                  出的對(duì)象就會(huì)泄露.于是,你可能會(huì)說(shuō):那么就捕獲異常來(lái)保證安全性好了.
                  你寫(xiě)這樣的程式:

                  void fook(){
                  A* m_PTRx = new A(m_PARAMin);
                  try{
                      m_PTRx->DoSomething();
                  }
                  catch(..){
                      delete m_PTRx;
                      throw;
                  }
                  delete m_PTRx;
                  }
                  哦!天哪!想象一下,你的系統(tǒng),是否會(huì)象專(zhuān)為捕獲異常而設(shè)計(jì)的.

                  一天,有人給你建議:"用Smart Pointer,那很安全.".你可以這樣重寫(xiě)你的程序:
               
                  void fook(){
                  auto_ptr<x> m_SMPTRx(new x(m_PARAMin));
                  m_SMPTRx->DoSomething();
                  }

                  OK!你不太相信.不用delete嗎?
                  是的.不用整天提心吊膽的問(wèn)自己:"我全部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并不可幫你管理數(shù)組資源    
                  
                  no2.
                  vector<auto_ptr<x>> m_VECsmptr;
                  m_VECsmptr.push_back(auto_ptr<int>(new int(100)));
                  //auto_ptr并不適合STL內(nèi)容.
                  
                  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

                  預(yù)先提及所有權(quán)的問(wèn)題,以便下面帶著疑問(wèn)剖析代碼?

                  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中,我要告訴你對(duì)象所有權(quán)轉(zhuǎn)移了兩次.
                  //什么叫對(duì)象所有權(quán)呢?
              
                2. std::auto_ptr的設(shè)計(jì)原理
                  
                  上面的一片正確用法,它們?cè)诟尚┦裁?
                        一片非法,它們犯了什么罪?
                        一片什么所有權(quán)轉(zhuǎn)移,它的內(nèi)部機(jī)智是什么?
                  哦!一頭霧水?下面我們就來(lái)剖析其實(shí)現(xiàn)機(jī)制.
                  基礎(chǔ)知識(shí):
                          a.智能指針的關(guān)鍵技術(shù):在于構(gòu)造棧上對(duì)象的生命期控制
                            堆上構(gòu)造的對(duì)象的生命期.因?yàn)樵谥悄苤羔樀膬?nèi)部,存儲(chǔ)
                            著堆對(duì)象的指針,而且在構(gòu)析函數(shù)中調(diào)用delete行為.
                            大致機(jī)構(gòu)如下:
                            x* m_PTRx = new x(100);//#1
                            template<typename T>
                            auto_ptr{
                            private:
                            T* m_PTR;//維護(hù)指向堆對(duì)象的指針,在auto_ptr定位后    
                            ....     //它應(yīng)該指向#1構(gòu)造的對(duì)象,即擁有所有權(quán).
                            ~auto(){ delete m_PTR; }
                            ....
                            }
                         b.所有權(quán)轉(zhuǎn)移之說(shuō)
                           上面曾有一非法的程式片段如下:
                           auto_ptr<x> m_SMPTR1(new x(100));
                           auto_ptr<x> m_SMPTR2 = m_SMPTR1;
                           m_SMPTR2->print();
                           //輸出:100.
                           m_SMPTR1->print();
                           //!! 非法的.
                           按常理來(lái)說(shuō),m_SMPTR->print();怎么是非法的呢?
                           那是因?yàn)楸緛?lái),m_SMPTR1維護(hù)指向new x(100)的指針,
                           可是m_SMPTR2 = m_SMPTR1;auto_ptr內(nèi)部機(jī)制使得m_SMPTR1將對(duì)象的地址
                           傳給m_SMPTR2,而將自己的對(duì)象指針置為0.
                           那么自然m_SMPTR->print();失敗.
                           這里程序設(shè)計(jì)者要負(fù)明顯的職責(zé)的.
                           那么auto_ptr為什么采取這樣的策略:保證所有權(quán)的單一性.
                                                           亦保證了系統(tǒng)安全性.
                           如果多個(gè)有全權(quán)的auto_ptr維護(hù)一個(gè)對(duì)象,那么在你消除一個(gè)
                           auto_ptr時(shí),將導(dǎo)致多個(gè)auto_ptr的潛在危險(xiǎn).
                 
                   下面我們以SGI-STL的auto_ptr設(shè)計(jì)為樣本(去掉了無(wú)關(guān)分析的宏),來(lái)剖析其原理.
                   #1  template <class _Tp> class auto_ptr {
                   #2  private:
                   #3  _Tp* _M_ptr;  //定義將維護(hù)堆對(duì)象的指針

                   #4  public:
                   #5  typedef _Tp element_type;  //相關(guān)類(lèi)型定義
                   #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構(gòu)造函數(shù)的三個(gè)版本.
                       //#6注釋?zhuān)簜魅雽?duì)象的指針,構(gòu)造auto_ptr.explicit關(guān)鍵字:禁止隱式轉(zhuǎn)換.
                       //        這就是ok2正確,而no5(隱式轉(zhuǎn)換)錯(cuò)誤的原因.
                       //#7注釋?zhuān)嚎截悩?gòu)造函數(shù).
                       //        傳入auto_ptr實(shí)例,構(gòu)造auto_ptr. ok1、ok3使用了這個(gè)構(gòu)造式.
                       //        它是一個(gè)很關(guān)鍵的構(gòu)造函數(shù),在具體情況下,我們?cè)俜治?br>           //#8注釋?zhuān)篴uto_ptr的模板成員,可在繼承對(duì)象重載的基礎(chǔ)上,實(shí)現(xiàn)特殊功能.
                       //  
                       //   舉例:
                       //   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));//實(shí)質(zhì):
                       //   auto_ptr<B> m_SMPTRb(m_SMPTRa); //基類(lèi)的指針可以賦給派生類(lèi)的指針         
                       //             
                       //   auto_ptr<B> m_SMPTRb(new B(44));//實(shí)質(zhì):
                       //   auto_ptr<A> m_SMPTRa(m_SMPTRb); //派生類(lèi)的指針不可賦給基類(lèi)的指針
                       //      
                       //   auto_ptr<A> m_SMPTRa(new B(33));  // ok! 
                       //   m_SMPTRa->fook()將調(diào)用派生類(lèi)B的fook()
                       //   m_SMPTRa->A::fook()將調(diào)用基類(lèi)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 兩個(gè)版本的指派函數(shù).
                      //         delete _M_ptr; 在指派前,銷(xiāo)毀原維護(hù)的對(duì)象.
                      //         _a.release() ; release操作,詳細(xì)代碼參見(jiàn)#20~~#23.
                      //                        用于*this獲得被指派對(duì)象,
                      //                        且將原維護(hù)auto_ptr置空.
                      //     no3使用了第一種指派.
                      //     而權(quán)限轉(zhuǎn)移正是_a.release()的結(jié)果.
                     
                   #17 ~auto_ptr() __STL_NOTHROW { delete _M_ptr; }
                      //構(gòu)析函數(shù).消除對(duì)象.注意這里對(duì)對(duì)象的要求!
                     
                   #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注釋?zhuān)禾犷I(lǐng)操作(dereference),獲得對(duì)象. 見(jiàn)ok5用法.
                     // #18注釋?zhuān)撼蓡T運(yùn)算符重載,返回對(duì)象指針.
                     // #19注釋?zhuān)浩胀ǔ蓡T函數(shù).作用同于重載->運(yùn)算符
                     //
                   #20 _Tp* release() __STL_NOTHROW {
                   #21 _Tp* __tmp = _M_ptr;
                   #22 _M_ptr = 0;
                   #23 return __tmp;                }
                     //上面已經(jīng)詳解     
             
                   #24 void reset(_Tp* __p = 0) __STL_NOTHROW {
                   #25 delete _M_ptr;
                   #26 _M_ptr = __p;                          }
                     //
                     //傳入對(duì)象指針,改變auto_ptr維護(hù)的對(duì)象
                     //       且迫使auto_ptr消除原來(lái)維護(hù)的對(duì)象
                     //       見(jiàn)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.
                    
                     //下面這片段用于類(lèi)型轉(zhuǎn)化,目前沒(méi)有任何編譯器支持
                     //具體技術(shù)細(xì)節(jié)不訴.         

                     #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!就是這樣了.
                  正如上面原理介紹處敘說(shuō),
                  你需要正視兩大特性:
                  1.構(gòu)造棧對(duì)象的生命期控制堆上構(gòu)造的對(duì)象的生命期
                  2.通過(guò)release來(lái)保證auto_ptr對(duì)對(duì)象的獨(dú)權(quán).
                 
                 在我們對(duì)源碼分析的基礎(chǔ)上,重點(diǎn)看看:
                 no系列錯(cuò)誤在何處?
                 no1.
                     我們看到構(gòu)析函數(shù)template<class _Tp>
                                     ~auto_ptr() _STL_NOTHROW
                                    { delete _M_ptr; }
                     所以它不能維護(hù)數(shù)組,
                     維護(hù)數(shù)組需要操作: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的操作行為.
                   兵分兩路,可是再向下看,你會(huì)發(fā)現(xiàn),無(wú)一例外,都
                   通過(guò)const _Tp& 進(jìn)行拷貝行為,那么從auto_ptr提出的片段就
                   派上用場(chǎng)了.
                   可你知道的,auto_ptr總是堅(jiān)持對(duì)對(duì)象的獨(dú)權(quán).那必須修改
                   原來(lái)維護(hù)的對(duì)象,而vector行為要求const _Tp&,這樣自然會(huì)產(chǎn)生
                   問(wèn)題.一般編譯器是可以發(fā)覺(jué)這種錯(cuò)誤的.

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

                 no3.
                    這個(gè)也是auto_ptr隱含的所有權(quán)問(wèn)題引起的.
                    const auto_ptr不允許修改.
                    隨便提及:const對(duì)象不代表對(duì)象一點(diǎn)不可以改變.
                              在兩種const語(yǔ)義下,都有方法修改對(duì)象或?qū)ο髢?nèi)部指針維護(hù)的對(duì)象
                             或其它資源.
                 no4.
                    再看auto_ptr的構(gòu)析函數(shù).
                    delete不可以消除棧上資源.

                 no5.
                    依賴(lài)傳入對(duì)象指針的構(gòu)造函數(shù)被聲明為explicit,禁止隱式轉(zhuǎn)換.

               
                3.auto_ptr高級(jí)使用指南
                 
                  a.類(lèi)成員auto_ptr,禁止構(gòu)造函數(shù)以構(gòu)建"完全對(duì)象"
                    Programme1:
                    struct Structx{
                           int m_Idata;
                           char m_CHRdata;
                           /* and so on */
                    };
                    出于對(duì)象編程的理念,
                    我們將Structx打造成包裹類(lèi):
                    class StructWrapper{
                    private:
                    Structx* m_STRTxptr;
                    public:
                    StructWrapper():m_STRTxptr(new Structx){}
                    ~StructWrapper(){delete m_SMRTxptr; }
                    public:
                    void Soperator1(){ /* 針對(duì)Structx對(duì)象的特性操作 */}
                    void Soperator2(){ /* 針對(duì)Structx對(duì)象的特性操作 */}       
                    /*  and so on */
                    };
                   
                    Programme2:
                    class StructWrapper{
                    private:
                    auto_ptr<Structx> m_SMPTRx;
                    public:
                    StructWrapper():m_SMPTRAx(new Structx){}
                    public:
                    void Soperator1(){ /* 針對(duì)Structx對(duì)象的特性操作 */}
                    void Soperator2(){ /* 針對(duì)Structx對(duì)象的特性操作 */}       
                    /*  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;
                    };

                    處于對(duì)構(gòu)建于堆中的對(duì)象(new Structx)智能維護(hù)的需要.
                    我們將programme1改造為programme2:
                    不錯(cuò),對(duì)象是可以智能維護(hù)了.
                    對(duì)于包裹類(lèi)(StructWrapper)你是否會(huì)有這樣的構(gòu)造或指派操作:
                     StructWrapper m_SMPTRWrapper2(m_SMPTRWrapper1);
                  
                     StructWrapper mSMPTRWrapper2 = m_SMPTRWrapper1;
                     那么請(qǐng)注意:
                     當(dāng)你坦然的來(lái)一個(gè):M_SMPTRWrapper1->Soperator1();的時(shí)候,
                     系統(tǒng)崩潰了.
                     不必驚訝,所有權(quán)還是所有權(quán)問(wèn)題.
                     問(wèn)一下自己:當(dāng)programme2默認(rèn)拷貝構(gòu)造函數(shù)作用時(shí),又調(diào)用了auto_ptr的
                     默認(rèn)構(gòu)造函數(shù),那么auto_ptr所有的默認(rèn)行為都遵循獨(dú)權(quán)策略.對(duì),就這樣.
                     m_SMPTRWrapper1的對(duì)象所有權(quán)轉(zhuǎn)移給了m_SMPTRWrapper2.
                     M_SMPTRWrapper1->Soperator1();那么操作變成了在NULL上的.
                     哦!系統(tǒng)不崩潰才怪.
                     那么你需要想,programme3那樣利用auto_ptr的提領(lǐng)操作符自己的
                     構(gòu)造"完全對(duì)象".

                   b.利用const關(guān)鍵字,防止不經(jīng)意的權(quán)限轉(zhuǎn)移
                    
                     從上面的敘述,你可看出,所有權(quán)轉(zhuǎn)移到處可以釀成大禍.
                     而對(duì)于一般應(yīng)用來(lái)說(shuō),獨(dú)權(quán)又是很好的安全性策略.
                     那么我們就用const來(lái)修飾auto_ptr,禁止不經(jīng)意的錯(cuò)誤.
                   
                     當(dāng)然上面提及:并不代表auto_ptr是不可修改的.
                     處于需要,從兩種const語(yǔ)義,你都可實(shí)現(xiàn)修改.

                     然,你還希望在函數(shù)傳入傳出auto_ptr那么你可傳遞auto_ptr的引用,
                     那就萬(wàn)無(wú)一失了: void fook(const auto_ptr<x>& m_PARAMin);
                     在返回后賦予其它時(shí),使用引用是不行的.你得用指針.
                     因?yàn)橐脽o(wú)論作為lvalue還是rvaluev,都會(huì)調(diào)用構(gòu)造或指派函數(shù).


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

                  下面在需求層面上,我們思索一下我們的智能指針還需要些什么?
             
                    a. std::auto_ptr 能夠處理數(shù)組嗎?我們可以用智能指針來(lái)管理其它的資源嗎?
                       譬如一個(gè)線(xiàn)程句柄、一個(gè)文件句柄 and so on !
                    b. 對(duì)于我們的對(duì)象真的永遠(yuǎn)實(shí)行獨(dú)權(quán)政策嗎?
                    c. Our 智能指針還需要在繼承和虛擬層面上發(fā)揮威力 !
                    d. 往往,需要擴(kuò)展Our 智能指針的功能成員函數(shù)來(lái)滿(mǎn)足動(dòng)態(tài)的需要 !
                    e. 也許,你需要的還很多.

            ---------------------------------------------------------------
                                   [下續(xù)]

            二、C++條件,尋找構(gòu)造更強(qiáng)大的智能指針(Smart Pointer)的
                策略
               
                1.支持引用記數(shù)的多種設(shè)計(jì)策略
                2.支持處理多種資源
                3.支持Subclassing
                4.支持多線(xiàn)程條件下,線(xiàn)程安全的多種設(shè)計(jì)策略
                5.其它多種特殊要求下,再構(gòu)造

            三、Generic Programming基礎(chǔ)技術(shù)和Smart Pointer
                1.回首處理資源中的Traits技術(shù)
                2.回首多線(xiàn)程支持的設(shè)計(jì)


            四、COM實(shí)現(xiàn)中,Smart Pointer設(shè)計(jì)原理


            五、著名C++庫(kù)(標(biāo)準(zhǔn)和非標(biāo)準(zhǔn))中的Smart Pointer現(xiàn)狀

            -----------------------------------------------------------

            --------------------------------------------------------------
                                      鄭重聲明:
                             允許復(fù)制、修改、傳遞或其它行為
                             但不準(zhǔn)用于任何商業(yè)用途.
                                  寫(xiě)于  20/3/2003
                                  最后修改: 20/3/2003
                                     By RedStar81
                                  81_RedStar@163.com
            -------------------------------------------------------------     

            posted on 2008-09-22 00:37 kzhang 閱讀(2685) 評(píng)論(1)  編輯 收藏 引用 所屬分類(lèi): C++語(yǔ)言

            FeedBack:
            # re: [轉(zhuǎn)]C++深度探索系列:智能指針(Smart Pointer) [一]
            2013-06-09 09:07 | atlas
            請(qǐng)教下,這篇文章轉(zhuǎn)載自哪里?有沒(méi)有后續(xù)[二]啊?  回復(fù)  更多評(píng)論
              

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



            <2013年6月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            30123456

            常用鏈接

            留言簿

            隨筆分類(lèi)

            隨筆檔案

            文章分類(lèi)

            文章檔案

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久久久久无码Av成人影院| 久久ww精品w免费人成| 国内精品久久久久久99| 国产精品久久午夜夜伦鲁鲁| 99久久精品国产一区二区| 亚洲欧洲精品成人久久奇米网| 亚洲欧美日韩精品久久亚洲区| 99精品国产免费久久久久久下载| 18岁日韩内射颜射午夜久久成人| 久久精品一本到99热免费| 久久人人爽人人爽人人片AV东京热| 久久久久久九九99精品| 久久99精品久久久久久9蜜桃 | 久久青青草原国产精品免费| 国产精品久久久久久久久免费| 超级碰久久免费公开视频| 亚洲午夜精品久久久久久浪潮| 人妻精品久久久久中文字幕一冢本 | 久久久久久亚洲精品无码| 久久精品国产亚洲αv忘忧草| 99国产欧美久久久精品蜜芽| 伊人久久大香线蕉无码麻豆| 九九精品99久久久香蕉| 久久久久久国产a免费观看黄色大片 | 色8久久人人97超碰香蕉987| 久久亚洲天堂| 久久精品国产免费一区| 久久久久se色偷偷亚洲精品av| 狠狠色婷婷综合天天久久丁香| 久久水蜜桃亚洲av无码精品麻豆| 久久这里的只有是精品23| 深夜久久AAAAA级毛片免费看| 久久综合综合久久97色| 久久婷婷五月综合色高清| 精品无码久久久久国产动漫3d| 精品人妻伦九区久久AAA片69 | 久久成人国产精品一区二区| 99久久精品国产高清一区二区 | 色偷偷偷久久伊人大杳蕉| 久久99精品久久久久久噜噜| 日本福利片国产午夜久久|