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

ATL 開發技巧:以介面陣列實作集合對象,簡化枚舉器複雜度

     編輯:關於VC++

動機:為什麼不使用標準枚舉器?

集合對象通常透過枚舉器(IEnumVARIANT)實現訪問控制,但需定義複雜的複製策略與集合方法。若僅需簡單的索引訪問,介面陣列提供更輕量的替代方案。本文示範以介面陣列實作集合對象的完整範例。

範例架構

角色類別名介面名
集合建立類CVoxSysIVoxSys
集合對象類CVoxChsIVoxChs
子對象類CVoxChIVoxCh

1. 子對象 CVoxCh:單一資料項

私有成員


private:
  BSTR m_bstrMessage;

建構子初始化


CVoxCh() { m_bstrMessage = A2BSTR("No inited!"); }

介面屬性 Message (BSTR)


STDMETHODIMP CVoxCh::get_Message(BSTR* pVal) {
  *pVal = m_bstrMessage;
  return S_OK;
}

2. 集合對象 CVoxChs:管理子對象陣列

私有成員:固定大小介面陣列 + 計數器


private:
  CComPtr m_arrpCh[160]; // 子對象介面陣列
  long m_nChs;                   // 實際子對象數

建構子


CVoxChs() { m_nChs = 0; }

介面定義 (IDL)


// 新增子對象
[id(1), helpstring("method AddCh")] HRESULT AddCh([out, retval] long* pVal);
// 取得子對象數量
[propget, id(2), helpstring("property Count")] HRESULT Count([out, retval] long* pVal);
// 依索引取得子對象介面
[propget, id(3), helpstring("property Ch")] HRESULT Ch([in] long index, [out, retval] IVoxCh** pVal);

方法實作


// AddCh:建立新子對象並加入陣列
STDMETHODIMP CVoxChs::AddCh(long* pVal) {
  CVoxCh::CreateInstance(&m_arrpCh[m_nChs]);
  m_nChs++;
  *pVal = 0; // 回傳索引 0 (或可回傳實際索引)
  return S_OK;
}

// get_Count
STDMETHODIMP CVoxChs::get_Count(long* pVal) {
  *pVal = m_nChs;
  return S_OK;
}

// get_Ch:透過 CComPtr::CopyTo 安全複製介面指標
STDMETHODIMP CVoxChs::get_Ch(long index, IVoxCh** pVal) {
  return m_arrpCh[index].CopyTo(pVal);
}

關鍵點:CComPtr::CopyTo() 自動處理 AddRef(),確保呼叫端獲得有效介面指標。

3. 集合建立類 CVoxSys:提供集合對象入口

私有成員


private:
  CComPtr m_spVoxChs;

FinalConstruct() 初始化集合對象


// 使用 FinalConstruct 因其可回傳標準 HRESULT
HRESULT CVoxSys::FinalConstruct() {
  return CVoxChs::CreateInstance(&m_spVoxChs);
}

介面屬性 VoxChs


[propget, id(1), helpstring("property VoxChs")] HRESULT VoxChs([out, retval] IVoxChs** pVal);

STDMETHODIMP CVoxSys::get_VoxChs(IVoxChs** pVal) {
  return m_spVoxChs.CopyTo(pVal);
}

使用說明與注意事項

  1. 編譯註冊組件後,使用前必須先呼叫 AddCh() 新增子對象實例,再進行存取,符合一般程式設計邏輯。
  2. 陣列大小固定為 160,避免超出索引範圍。
  3. 此實作適合子對象數量可控、不需複雜枚舉語義的場景。若需 for each、IEnumVARIANT 相容性,仍應實作標準枚舉器。

總結

以介面陣列 (CComPtr<T>[]) 替代枚舉器,可大幅簡化集合對象實作:無需定義複製策略、無需實作 Next/Skip/Reset/Clone,只需 Add、Count、Item(index) 三個核心成員。配合 CComPtr 自動引用計數管理,代碼簡潔且安全。適用於內部工具、輕量級組件或原型開發。

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