剖析ATL、WTL CString的實(shí)現(xiàn)
話說(shuō)CString這個(gè)東西困擾了很多年輕人,因?yàn)樗鼤?huì)引起詭異的編譯錯(cuò)誤,今天跟著我一起來(lái)深入ATL、WTL頭文件,來(lái)把這個(gè)東西搞個(gè)清清楚楚。
涉及到頭文件
ATL : atlstr.h, atlsimpstr.h
MFC : cstringt.h、afxstr.h
WTL : atlmisc.h
ATL和MFC有關(guān)剪不斷理還亂的關(guān)系,為了更容易分析,我們先要理清這四個(gè)頭文件間的關(guān)系。觀察相互間觀察順序,可以得出:atlstr.h引用cstringt.h,cstring引用atlsimpstr.h,afxstr.h引用cstringt.h,由此可得出下圖:
atlsimpstr.h 都干了什么
1、定義了 CStringData 和 CNilStringData 類
2、定義了 ChTraitsBase 類,類如下:
此類比較簡(jiǎn)單,功能是為不同的字符類型,建立新的統(tǒng)一的名稱。另外,這里使用到了模板特化技術(shù)。
3、定義了CSimpleStringT類,此類的功能是,在ChTraitBase定義的統(tǒng)一名稱的基礎(chǔ)上,提供字符串一些基本的操作功能函數(shù)。
t_bMFCDLL可無(wú)視。另外,注意,此處所操作的字符串對(duì)象,都是CStringData。
總述:在atlsimpstr.h中,我們發(fā)現(xiàn)了3個(gè)令人感興趣的東西,CStringData 是字符串操作單元,ChTraitBase提供字符串變量統(tǒng)一命名服務(wù),而CSimpStringT是一個(gè)基于CStringData字符串操作單元的簡(jiǎn)易的CString(注意,只是簡(jiǎn)易,其中并未提供我們常用的CString中的那些函數(shù))。
cstringt.h 都干了什么
1、定義了 ChTraitsCRT 類,如下:
該類繼承atlsimpstr.h中的 ChTraitsBase 類,然后在父類提供服務(wù)的基礎(chǔ)上,提供一系列字符串底層操作函數(shù)。思考:為什么此處用繼承?而CSimpleStringT使用提t(yī)ypedef?
2、定義了 _MFCDLLTraitsCheck 類,如下:
這里再一次用到了模板特化技術(shù),該類用于檢測(cè)當(dāng)前使用的StringTraits是ATL定義的還是MFC定義的。(ATL定義的叫StrTraitATL,MFC定義的叫StrTraitMFC,后面會(huì)提到)
3、定義了 CStringT 類,如下:
注意了,CStringT 就是CString的真身!前面說(shuō)到,CSimpStringT操作CStringData字符串操作單元,提供基本的字符串操作功能,而CStringT繼承CSimpleStringT,利用StringTraits,包裝更高級(jí)的功能函數(shù)。而這些更高級(jí)的功能函數(shù),就是我們通常調(diào)用CString時(shí)所使用到的那些函數(shù)。
atlstr.h 都干了什么
1、定義了 CAtlStringMgr 類。
2、定義了 ChTraitsOS 類,如下:
和 ChTraitCRT相對(duì)應(yīng),ChTraitsOS繼承atlsimpstr.h中的 ChTraitsBase 類,然后在父類提供服務(wù)的基礎(chǔ)上,提供一系列字符串底層操作函數(shù)。
和 ChTraitCRT相比,他倆提供的函數(shù)大部相關(guān),少數(shù)不同,另外相同函數(shù)名的實(shí)現(xiàn)不一定相同。
3、定義了 StrTraitATL 類,如下:
和 StrTraitMFC相對(duì)應(yīng),該類提供字符串資源管理函數(shù)和CStringData內(nèi)存管理器的ATL版。
4、定義了CSTRING,如下:
afxstr.h 都干了什么
1、定義了 StrTraitMFC,如下:
上文已述,和StrTraitATL相對(duì),本類提供的功能實(shí)現(xiàn)都封閉在MFC中。
2、定義了CString,如下:
atlmisc.h 都干了什么
打開atlmisc.h,可以發(fā)現(xiàn)此文件只不過(guò)是定義了一些結(jié)構(gòu)體,定義了一個(gè)CString的簡(jiǎn)易版。因?yàn)锳TL CString依賴于MFC頭文件,所以,如果在使用CSTRING而又不想加入過(guò)多其它文件時(shí),WTL CSTRING提供了一個(gè)很好的選擇。
所有文件都分析后,我們發(fā)現(xiàn),atl、mfc、wtl分別定義了一個(gè)CString。其中atl和mfc中的CString都是基于CStringT,只有一個(gè)地方是不同的,即CStringT所引用的StringTrait(即StrTraitsATL 還是 StrTraitMFC)。而WTL CString 的實(shí)現(xiàn)是獨(dú)立的,是一個(gè)真正的類。另外 ,StringTrait引用的Iterator是可選的(即底層字符串操作封裝)。
最后,我們發(fā)現(xiàn)ATL和MFC中涉及CString的類關(guān)系有些復(fù)雜,我希望畫一個(gè)圖來(lái)更好的描述各個(gè)類間的相互關(guān)系,這個(gè)圖將放在下一篇隨筆……
【編輯推薦】