參考計數規則

文章翻譯 文章翻譯
文章編號: 104138 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

結論

元件物件模型中介面的存留期 (Lifetime) 被控制透過參考計數。參考計數為介面則是透過繼承自 IUnknown [AddRef() 和 Release() 成員函數操作。介面的參考計數和 Release() 方法遞減 AddRef() 成員會遞增它。一旦介面的參考計數前往零,有不再該介面的任何有效指標。如果所有物件的介面上將參考次數為零,然後物件可以被釋放因為不再有任何物件的指標。

其他相關資訊

參考計數規則

下列清單是一份參考計數 (取自頁 83 與 OLE 2.0 規格 84) 所必須遵守規則。小的程式碼範例已經加入以協助釐清規則本文中。

  1. 每一份新的介面指標必須是的 AddRef () 可以,而且每個解構的介面指標必須想除外 () 的發行位置後續規則明確允許否則。

    1. 在 Out 參數到函式: 呼叫者必須 AddRef() 實質參數,out-value 存放在它的上方時因為它會發行 () 可以由被呼叫端。
            LPOLEOBJECT lpObject;
               .
               .  // Get pointer to IOleObject.
               .
            LPVIEWOBJECT lpView = lpObject;
      
            lpObject->AddRef()
      
            // GetViewObject is a theoretical function that takes a
            // pointer to anything derived from IUnknown, and then
            // returns a pointer to IViewObject in the same variable
            // passed as the parameter. The AddRef() above is needed so
            // that the original pointer to IOleObject is not freed.
      
            GetViewObject(lpView);
      								
    2. 擷取全域變數: 從現有的複本,指標在全域變數中擷取介面指標的本機複本必須是獨立本機複本仍在執行時,計算因為呼叫函式的參考可能摧毀中之全域複本。
            void function()
            {
            // Get a pointer to IOleObject from a global variable.
            LPOLEOBJECT lpOleObject = glpObject;
      
            // This AddRef() is needed so that the interface
            // pointed to by the global variable, glpObject,
            // does not get released by a different part of
            // the applications code.
      
            lpOleObject->AddRef();
               .
               . // use lpOleObject;
               .
            lpOleObject->Release();
            }
      								
    3. 合成超出細的空中"的新指標: A synthesizes 使用特殊的內部知識,而不是從其他來源取得必須執行的初始 AddRef() 新合成指標上的介面指標的函式。 這種常式的重要範例包括執行個體建立常式 IUnknown::QueryInterface,等等的實作。
            STDMETHDOIMP IUnknown::QueryInteface( REFIID iidInterface,
                                               LPVOID FAR *ppvObj)
            {
            *ppvObj = NULL;
            SCODE sc = E_NOINTERFACE;
      
            if (iidInterface == IUnknown)
                {
                *ppvObj = this;
      
                // This AddRef() is needed because a new pointer
                // was just created.
      
                AddRef();
               sc = S_OK;
                }
      
            return ResultFromScode(sc);
            }
      								
    4. 傳回一份內部儲存的指標: 一旦傳回的指標,被呼叫端具有不知道它的存留期 (Lifetime) 如何關聯使用者的滑鼠指標的內部預存的複本。因此,被呼叫端必須的 AddRef() 指標複製之前將它傳回。
            // m_lpOleObject is a private member variable of a C++ class.
            // GetOleObject is a member function to return access to this
            // pointer.
      
            void GetOleObject (LPVOID FAR *ppObject)
            {
                *ppObject = m_lpOleObject;
      
                // This AddRef() is needed due to this rule.
      
                m_lpOleObject->AddRef();
             }
      								
  2. 特殊知識的一段程式碼既開始和尾的兩個或多個份介面指標的存留時間的關係可以允許 AddRef()/Release() 組可省略。

    1. 在參數到函式: 做為實際的參數傳遞至函式的介面指標的複本有巢狀方式置於,用來初始化值指標的存留期。因此,實際參數需要不會分別計算的參考。
            void function (LPOLEOBJECT lpOleObject)
            {
      
            // Can use lpOleObject in this function
            // without doing AddRef() and Release().
      
            }
      								
    2. 從包括傳回值的函式外傳參數: 設定 [out 參數函式本身由規則 1 必須有穩定的介面指標複本。在結束,負責釋放指標是從被呼叫端傳輸到呼叫端。因此,out 參數需要不能參考計數。
            LPVIEWOBJECT lpView;
      
            HERROR hErr = lpOleObject->QueryInterface(IID_IViewObject,
                                                      (LPVOID FAR *)lpView);
      
            if (hErr = NOERROR)
                {
                // The QueryInterface succeeded. lpView does not have
                // to be AddRef()'d because it has already been done
                // by the QueryInterface method.
                }
      								
    3. 本機變數: 一個函式實作清楚地具有 omniscient 知識的每個配置在堆疊框架上的指標變數的存留期。因此,它可以使用這項知識省略多餘 AddRef()/Release() 配對。
            void function()
            {
            LPOLEOBJECT lpTempObject;
               .
               .
               .
            lpTempObject = lpObject;
               .
               .  // lpTempObject can be used
               .  // without reference counting as long as
               .  // it is known that the lifetime of lpObject
               .  // outside of this function call.
               .
            }
      								
    4. Backpointers: 某些資料結構是包含兩個元件 A 和 B 每一個都有另一個指標的性質。如果已知某元件 (A) 的存留期 (Lifetime) 包含的其他 (B),存留期 (Lifetime),然後從第二個元件指標回第一個 (從 A 到 B) 必須不能參考計數。通常,避免否則就會建立在週期是很重要的維護適當的釋放行為。

屬性

文章編號: 104138 - 上次校閱: 2003年12月3日 - 版次: 3.1
這篇文章中的資訊適用於:
  • Microsoft OLE 2.0
  • Microsoft OLE 4.0?應用於:
    • Microsoft Windows NT 4.0
    • Microsoft Windows NT 3.51 Service Pack 5
    • Microsoft Windows NT 4.0
    • Microsoft Windows 95
    • the operating system: Microsoft Windows 2000
關鍵字:?
kbmt kbprogramming KB104138 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:104138
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com