atl中常見的模板使用手法

2021-09-30 02:13:17 字數 1580 閱讀 1612

1、傳入基類,繼承實現

在設計com介面時,經常會遇到這樣的情況:設計乙個基介面,其他多個介面繼承該介面。乙個典型的例子是iunknown介面,所有的com介面必須從iunknown介面繼承,而這些介面的實現都是相同的,我們不可能為每乙個com介面寫乙個iunknown介面的實現。iunknown介面的實現比較複雜,分布在幾個類中(可參考《深入解析atl》)。比較直觀的乙個例子是idispatch介面的實現,通常需要實現idispatch介面的類都從idispatchimpl繼承。這個結構是這樣的:

class atl_no_vtable cbbb :

public idispatchimpl

template

class atl_no_vtable idispatchimpl : public t

這樣,每個需要實現idispatch介面的類都只需要從idispatchimpl繼承即可。

idispatchimpl的做法其實相當簡單,僅僅是引入了乙個實現類而已。

另一種常見的情況是分離介面和實現。比如有以下的介面繼承結構:

inte***ce ibase

;inte***ce iderive1 : public ibase

;inte***ce iderive2 : public ibase

;ibase對應的實現類如下:

class cbase : public ibase

};這裡假設有乙個類cderive1需要繼承介面iderive1和實現類cbase,如果直接從兩個類繼承,象這樣:

class cderive1 : public cbase,public iderive1

};當使用cderive1類時,編譯器會抱怨模稜兩可。很自然的,考慮到用虛擬繼承解決:

inte***ce iderive1 : virtual public ibase

;class cbase : virtual public ibase

};class cderive1 : public cbase,public iderive1

};一切看起來都很完美,virtual繼承解決了模稜兩可問題。但是虛擬繼承是很多產生複雜性問題的根源,難以擴充套件和維護.

看來我們還是只有老老實實加乙個中間層吧。最終解決方案如下:

template

class cbase : public tbase

};class cderive1 : public cbase

};2、傳入子類

在atl中,有大量的以下用法:

template

class cb

};這裡傳進來的是cb的子類

class cd : public cb

};這種技術實際上有點象虛函式.

以上語句t* pt = static_cast(this)之所以能編譯通過是因為模板類cb在編譯期間已被例項化為cb,編譯器已經知道t就是cd,而cd繼承自cb,所以從cb向cd轉型是安全的.這種手法的乙個好處是不需要乙個t型別的物件,直接可以使用this指標安全轉型.其2,避免了虛函式呼叫的開銷,雖然虛函式的開銷是很小的,單繼承情況下幾乎可以忽略不計,但是虛函式的存在不利於編譯器的優化,而且static和inline虛函式也要出問題.

筆記 3 String中常見API的使用 一

package com.tedu.string length 返回當前字串物件中字元的個數,實際上就是char型別陣列的長度 author wildmess public class strlengthdemo package com.tedu.string indexof string str 查...

筆記 3 String中常見API的使用 二

package com.tedu.string trim 方法功能是去掉當前字串倆邊的空格 author wildmess public class trimdeno package com.tedu.string charat int index 返回指定索引位置的字元,返回的是個char型別資料...

Jenkins使用過程中常見的問題

解決方案 5 重新訪問localhost 8080 二 構建時報 python 不是內部或外部命令,也不是可執行的程式 解決方案 python的路徑沒有新增到jenkins環境變數 1 回到首頁選擇 系統管理 系統設定 全域性屬性 選項 勾選 環境變數 點選 新增 按鈕 出現鍵值對輸入,鍵輸入pat...