# 參考計數規則

### 參考計數規則

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);      }								``
``      // 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();       }								``

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) 必須不能參考計數。通常，避免否則就會建立在週期是很重要的維護適當的釋放行為。
2.00 3.50 4.00

#### 警告：本文為自動翻譯

Microsoft OLE 2.0, Microsoft OLE 4.0

• kbmt kbprogramming KB104138 KbMtzh
##### 意見反應
://c.microsoft.com/ms.js">