1. 程式人生 > >深度探索智慧指標(Smart Pointer)

深度探索智慧指標(Smart Pointer)

主題索引:

一、剖析C++標準庫智慧指標(std::auto_ptr)
   
    1.Do you Smart Pointer?
    2.std::auto_ptr
的設計原理
    3.std::auto_ptr
高階使用指南
    4.
你是否覺得std::auto_ptr還不夠完美?

二、C++條件,尋找構造更強大的智慧指標(Smart Pointer)策略
   
    1.
支援引用記數的多種設計策略
    2.
支援處理多種資源
    3.
支援Subclassing
    4.
支援多執行緒條件下,執行緒安全的多種設計策略
    5.
其它多種特殊要求下,再構造

三、Generic Programming

基礎技術和Smart Pointer
    1.
回首處理資源中的Traits技術
    2.
回首多執行緒支援的設計

四、COM實現中,Smart Pointer設計原理

五、著名C++(標準和非標準)中的Smart Pointer現狀

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

一、剖析C++標準庫智慧指標(std::auto_ptr)
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<      //            .....
      //            }
      //
      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 A(m_PARAMin);
      try{
          m_PTRx->DoSomething();
      }
      catch(..){
          delete m_PTRx;
          throw;
      }
      delete m_PTRx;
      }
     
!天哪!想象一下,你的系統,是否會象專為捕獲異常而設計的.

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

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

然後,還有人告訴你,可以這樣用呢:
      ok1.
      auto_ptr m_SMPTR1(new x(m_PARAMin));
      auto_ptr m_SMPTR2(m_SMPTR1);  //#2
      May be you can code #2 like this :
          auto_ptr m_SMPTR2;
          m_SMPTR2 = m_SMPTR1;     
      ok2.
      auto_ptr m_SMPTR1(new int(32));
     
      ok3.
      auto_ptr m_SMPTR1;
      m_SMPTR1 = auto_ptr(new int(100));
     
也可以:
      auto_ptr m_SMPTR1(auto_ptr(new int(100)));
     
      ok4.
      auto_ptr m_SMPTR1(new x(m_PARAMin));
      m_SMPTR1.reset(new x(m_PARAMin1));
     
      ok5.
      auto_ptr m_SMPTR1(new x(m_PARAMin));
      auto_ptr m_SMPTR2(m_SMPTR.release());
      cout<<(*m_SMPTR2).m_Idata<
     
      ok6.
      auto_ptr fook(){
      return auto(new int(100));
      }
 
      ok7.............and so on
     
     
但不可這樣用:
     
      no1.  
      char* chrarray = new char[100];
      strcpy(chrarray,"I am programming.");
      auto_ptr m_SMPTRchrptr(chrarray);
      //auto_ptr
並不可幫你管理陣列資源    
      
      no2.
      vector m_VECsmptr;
      m_VECsmptr.push_back(auto_ptr(new int(100)));
      //auto_ptr
並不適合STL內容.
      
      no3.
      const auto_ptr m_SMPTR1(new x(100));
      auto_ptr m_SMPTR(new x(200));
     
      no4.
      x m_OBJx(300);
      auto_ptr m_SMPTR(&m_OBJx);
     
      no5
      x* m_PTR = new x(100);
      auto_ptr m_SMPTR = m_pTR;
     
      no6..........and so on

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

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

      power2.
      auto_ptr m_SMPTR(new x(100));
     
      auto_ptr returnfun(auto_ptr m_SMPTRin){
      return m_SMPTRin;
      }
     
      auto_ptr = returnfun(m_SMPTR);  //#5

      //在上面的#5,我要告訴你物件所有權轉移了兩次.
      //
什麼叫物件所有權呢?
  
 
   2. std::auto_ptr的設計原理上面的一片正確用法,它們在幹些什麼?
           
一片非法,它們犯了什麼罪?
           
一片什麼所有權轉移,它的內部機智是什麼?
     
!一頭霧水?下面我們就來剖析其實現機制.
     
基礎知識:
              a.
智慧指標的關鍵技術:在於構造棧上物件的生命期控制堆上構造的物件的生命期.因為在智慧指標的內部,儲存著堆物件的指標,而且在構析函式中呼叫delete行為.
               
大致機構如下:
                x* m_PTRx = new x(100);//#1
                template
                auto_ptr{
                private:
                T* m_PTR;//
維護指向堆物件的指標,auto_ptr定位後    
                ....     //
它應該指向#1構造的物件,即擁有所有權.
                ~auto(){ delete m_PTR; }
                ....
                }
             b.
所有權轉移之說上面曾有一非法的程式片段如下:
               auto_ptr m_SMPTR1(new x(100));
               auto_ptr 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-STLauto_ptr

相關推薦

深度探索智慧指標(Smart Pointer)

主題索引: 一、剖析C++標準庫智慧指標(std::auto_ptr)        1.Do you Smart Pointer?    2.std::auto_ptr的設計原理    3.std::auto_ptr高階使用指南    4.你是否覺得std::auto_p

C++深度探索系列:智慧指標(Smart Pointer) [二]

                                           深度探索智慧指標(Smart Pointer) 主題索引: 一、剖析C++標準庫智慧指標(std::auto_ptr)        1.Do you Smart Pointer?    2

c++智慧指標(smart pointer)詳解

Smart Pointer Deal with c++11’s smart pointer facility. brief Smart pointers are class objects that behave like built-in

智慧指標(smart pointer)(2):unique_ptr

Unique pointer:   Manages the storage of a pointer, providing a limited garbage-collection facility, with little to no overhead ov

C++中的智慧指標(smart pointer)

指標問題是在學習C++,以及運用C++進行軟體開發過程中經常碰到的問題。其中之一,就是“懸垂指標”。所謂懸垂指標,就是是指指標指向了一塊沒有分配給使用者使用的記憶體,結果未定義,往往導致程式錯誤,而且難以檢測。 用一個簡單的例子來說明懸垂指標: string *sp = n

【C++】智慧指標(Smart Pointer)

1. 傳統指標存在的問題 傳統指標存在諸多的問題,比如指標所指向的物件的生命週期問題,掛起引用(dangling references),以及記憶體洩露(memory leaks). 如下是一個傳統指標的使用過程 void Foo() {

C++ 智慧指標(Smart Pointer)

智慧指標具有非常強大的能力,謹慎而明智的選擇能帶來極大的好處。我不否認智慧指標的能力,雖然我在之前的否認過auto_ptr。可能由於我自身能力的限制,體會不到auto_ptr的好處,但這樣的可能性我覺得已經不大了。但auto_ptr是最簡單的智慧指標,在它的周圍存在大量的作品

[C++] 什麼是智慧指標(Smart Pointer)以及何時使用

答案 1 智慧指標是一個類,它封裝了一個原始的C++指標,以管理所指物件的生命期。沒有單一的智慧指標型別,但所有這些都嘗試以實用的方式抽象原始指標。 智慧指標應優先於原始指標。 如果你覺得你需要使用指標(首先要考慮你是否真的需要指標),你通常會想要使用智慧指

C++探索智慧指標

一、 RAII(Resource Acquisition Is  Initialization) 資源分配即初始化,定義一個類來封裝資源的分配和釋放,在建構函式完成資源的分配和初始化,在解構函式完成資源的清理,可以保證資源的正確初始化和釋放。 RAII是一種思想,智慧指標是RAII

智慧指標(Smart Pointers)

share_prt類 share_prt 也是一個類模板,使用時和vector一樣要說明型別。 shared_prt<string> p1; //這是一個指向string型別的智慧指標,使用預設建構函式初始化智慧指標,裡面含有一個NULL指標。 智慧

實現智慧指標Smart Pointer

#ifndef SMARTPTR_H_ #define SMARTPTR_H_ template<typename T> struct SmartPtr { explicit Smart

SMART POINTER智慧指標

智慧指標(smart pointer):智慧指標是其實是一個物件A,它帶有一個模針成員變數m_p.用該A管理m_p,通過這種管理機制,可以防止由於new而導致的記憶體洩漏.智慧指標物件在使用時像指標一樣.同時也具有一般物件的所有特徵.如果要注意以下幾點:1,物件之間的賦值:若

C++ 面向物件高階開發--pointer-like classes(智慧指標

C++的類設計出來可以像 1.一個指標 2.像一個函式。 先來看1,為了比一般指標做更多的東西。 如圖:智慧指標中一定帶一個一般的指標,而且必須寫上* 和 -> 的方法。 【迭代器其實也是一種智慧指標】 如圖,link_type就是那個真正的指標,黃色部分就

深度探索C++物件模型筆記《指標的型別》

一個指標,不管它指向哪一種資料型別,指標本身所需的記憶體大小是固定的,即4個位元組。 class Z{    //...... }; class X: public Z{   //...... }; 那麼X* Px; Z *Pz; int* Pi;又有何不同呢?

深度探索C++物件模型(2)——物件(2)——this指標調整

this指標調整 首先看程式碼示例: #include <iostream> using namespace std; class A { public: int a; A() { printf("A::A()的this指標是:%p!\n",this); } v

深度探索C++對象模型】第一章 關於對象

mar 基礎 對象 ssa 尋址 member 如果 virtual const 第一章 關於對象(Object Lessons) —— 本書作者:Stanley B.Lippman 一、前言 什麽是 C++ 對象模型:簡單的

深度探索C++對象模型讀書筆記(一)

復雜 理解 image play 基礎上 isp 靜態 布局 bject 《深度探索C++對象模型》這本書也算是學習C++面向對象編程的必備書了,打算花上幾天先簡單的看一遍,這種書看上好幾遍也不一定能理解太多,慢慢積累一點一滴吃透就好。下面把我看書過程中覺得比較有意義的摘錄

深度探索C++對象模型 PDF中文清晰版

mage water vpd epg ges pro http col ESS 下載鏈接:https://pan.baidu.com/s/1jsDuzjIkMe7osn8Shhzepg深度探索C++對象模型 PDF中文清晰版

條款17:以獨立語句將newed物件置入智慧指標

條款17:以獨立語句將newed物件置入智慧指標 如何理解這句話呢?先上程式碼 class Queue { public: Queue() {} ~Queue() {} }; int GetPriority(const int type) {return

1.1 c/c++智慧指標

c/c++智慧指標 (直接上程式碼) template <typename T> class sharePtr { public: sharePtr() { instance_ = new T(); } ~sharePtr() { delete instan