首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

COM 智慧指標完全指南:CComPtr、CComQIPtr 原理、用法與釋放陷阱避坑

     編輯:關於C語言

COM 介面指標需手動 AddRef/Release,極易洩漏或重複釋放導致崩潰。智慧指標以 RAII 封裝管理參考計數,本文解析原理、自製範例、ATL 兩大智慧指標用法與關鍵陷阱。

智慧指標核心原理

  • 重載 operator->() 轉發呼叫給內部原始指標。
  • 建構/複製時 AddRef,解構/賦值時 Release,引用計數歸零自動 delete 內部物件。
  • 屬於代理模式應用。

自製智慧指標教學範例

template<class T>
class JTSmartPointer {
    T *m_pData;
    RefCount *m_pRef;  // 參考計數器(執行緒安全)
public:
    JTSmartPointer(T *p) : m_pData(p), m_pRef(new RefCount) { m_pRef->AddRef(); }
    JTSmartPointer(const JTSmartPointer& sp) : m_pData(sp.m_pData), m_pRef(sp.m_pRef) { m_pRef->AddRef(); }
    ~JTSmartPointer() { if (m_pRef && m_pRef->Release() == 0) { delete m_pRef; delete m_pData; } }
    T& operator*() { return *m_pData; }
    T* operator->() { return m_pData; }
    JTSmartPointer& operator=(const JTSmartPointer& sp) { /* 處理自賦值、釋放舊、接管新、AddRef */ }
    JTSmartPointer& operator=(T *p) { /* 釋放舊、接管新裸指標、新 RefCount */ }
};

ATL 智慧指標:CComPtr vs CComQIPtr

常用操作速查

CComQIPtr<IFun> spFun;                    // 空指標
CComQIPtr<IFun> spFun(pOtherIF);           // 建構時自動 QI
CComQIPtr<IFun> spFun(pUnknown);           // 從 IUnknown QI
spFun = pOtherInterface;                   // 賦值自動 QI
spFun.CoCreateInstance(CLSID_X);           // 建立並 QI
if (spFun) { ... }                         // 判斷有效性
spFun->SomeMethod();                       // 呼叫介面方法
spFun.Release();                           // 正確釋放:內部 Release + 歸零
// spFun->Release();  // ❌ 絕對禁止!導致智慧指標內部指標成懸空野指標

關鍵陷阱總結

  1. 絕不呼叫 sp->Release():繞過智慧指標管理,造成雙重釋放或野指標。
  2. 函式參數傳遞智慧指標時,優先用 const 參考(void Func(const CComPtr<IFoo>& sp)),避免觸發複製建構/賦值導致額外 AddRef/Release。
  3. 若需傳遞給要求裸指標的 API,使用 sp.p 或 &sp.p(輸出參數)。
  4. CComQIPtr 無法直接定義 IUnknown*,需顯式模板參數指定 IID。

實務心得

「不想犧牲周末除崩潰,請無腦使用智慧指標。」—— 血淚經驗之談

全專案強制使用 CComPtr/CComQIPtr 管理介面指標,配合靜態分析工具檢查裸指標殘留,可消除 90% 以上 COM 記憶體/崩潰問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性CComPtr<T>CComQIPtr<T> / CComQIPtr<T, &IID>
功能基本智慧指標含 QueryInterface 能力,建構/賦值自動 QI
支援 IUnknown是需顯式指定 IID:CComQIPtr<IUnknown, &IID_IUnknown>
適用場景已知確切介面需動態查詢介面、跨介面轉換