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

COM 智能指針實戰:ATL CComPtr 與 CComQIPtr 深度解析

     編輯:關於C語言

前言

在 COM 開發中,手動管理引用計數(AddRef/Release)既繁瑣又容易出錯。ATL 提供的智能指針模板類 CComPtr 和 CComQIPtr 能夠自動處理引用計數,極大地簡化了代碼並提高了安全性。本文通過一個實例 ComTest 組件(實現 ICmd 和 IStr 兩個接口)演示三種常見的智能指針用法。

環境準備

#include <atlbase.h>
#include <atlcom.h>
// 方法一、二使用的頭文件
#include "ComTest_i.c"
#include "ComTest.h"
// 方法三使用 #import 導入類型庫
// #import "ComTest.tlb" no_namespace

#include <stdio.h>
#include <stdlib.h>
using namespace ATL;

方法一:CComPtr + CComQIPtr 手動 QueryInterface

最基礎的用法:先創建 IUnknown,再通過 QueryInterface 獲取具體接口指針。


CComPtr<IUnknown> pUnk;
CComQIPtr<ICmd> pCmd;
HRESULT hr;

hr = pUnk.CoCreateInstance(CLSID_Cmd, NULL, CLSCTX_INPROC);
hr = pUnk.QueryInterface(&pCmd); // 等同於創建 ICmd 對象

int sum;
hr = pCmd->Add(1, 2, &sum);
printf("%d\n", sum);

// 智能指針會自動 Release,但顯式調用也無妨
pUnk.Release();
pCmd.Release();

方法二:CComQIPtr 直接賦值(推薦)

利用 CComQIPtr 的賦值運算符重載,自動完成 QueryInterface,代碼更簡潔,且能輕鬆獲取多個接口。


CComPtr<IUnknown> pUnk;
pUnk.CoCreateInstance(CLSID_Cmd, NULL, CLSCTX_INPROC);

CComQIPtr<ICmd> pCmd = pUnk; // 自動 QI
CComQIPtr<IStr> pStr = pUnk; // 同一對象獲取另一接口

int sum;
pCmd->Add(1, 2, &sum);
printf("%d\n", sum);

CComBSTR bstr;
pStr->Cat((BSTR)"d", (BSTR)"e", &bstr);
printf("%S\n", bstr);

// 離開作用域自動 Release,顯式調用亦可
pStr.Release();
pCmd.Release();
pUnk.Release();

方法三:#import 導入類型庫使用 _Ptr 類型

#import 會生成帶有 Ptr 後綴的智能指針類型(如 ICmdPtr),用法類似 ADO,適合快速原型開發。


// 需取消註釋 #import 行
ICmdPtr cmd = NULL;
cmd.CreateInstance(__uuidof(Cmd));

int sum;
cmd->Add(1, 2, &sum);
printf("%d\n", sum);

cmd.Release(); // 必須顯式釋放

核心要點總結

  • 自動資源管理:智能指針在析構時自動調用 Release,防止內存洩漏。
  • 接口轉換:CComQIPtr 的賦值操作封裝了 QueryInterface,比手動調用更安全。
  • 錯誤處理:始終檢查 HRESULT 返回值,生產代碼中不可忽略。
  • 選擇建議:項目中已有類型庫首選方法三;純手工編碼或需精確控制時推薦方法二。

本文出自 “Studoc” 博客,原文地址:https://studoc.blog.51cto.com/1284909/282721

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved