《
Modern C++ Design
》
Loki
庫(kù)源碼讀解隨想
大牛
Andrei Alexandrescu
的《
Modern C++ Design
》討論的是
C++
語(yǔ)言的最前沿研究:
generative programming
。本書(shū)中譯版估計(jì)得要半年以后才能出來(lái),所以只能靠其所附源碼來(lái)窺測(cè)generative programming了。
目前,我剛將源碼讀解了約一半,等全部讀完,我會(huì)將我的讀解注釋放出來(lái)的。現(xiàn)在,現(xiàn)談一下我的感想。
??? 先扯得遠(yuǎn)一點(diǎn)。C++有兩個(gè)巨大優(yōu)點(diǎn):和C兼容,自由;有兩個(gè)巨大缺點(diǎn):和C兼容,復(fù)雜。C++極其復(fù)雜,很難掌握,而這正是“自由”的代價(jià)。C++語(yǔ)言是個(gè)多編程風(fēng)格的語(yǔ)言,它同時(shí)支持
過(guò)程化、基于對(duì)象、面向?qū)ο蟆⒎盒汀⑸尚?/span>
這5種編程思想,具有極其強(qiáng)大的表達(dá)能力,可以方便地將各種設(shè)計(jì)轉(zhuǎn)化為實(shí)現(xiàn)。
generic Programming
的思想精髓是基于接口編程(相對(duì)于OOP,連多態(tài)所需的基類(lèi)都不要了),它的技術(shù)出發(fā)點(diǎn)是選擇子,核心技術(shù)是:類(lèi)型推導(dǎo)、類(lèi)型萃取、特化/偏特化,其成果是STL庫(kù):一組通用容器和一組操作于通用容器上的通用算法。
generative programming
的思想精髓是基于策略編程(編譯器根據(jù)策略自動(dòng)生成所需代碼,由于具有更高的抽象性,所以代碼復(fù)用度也更高),在Loki庫(kù)的實(shí)現(xiàn)中,目前只使用了遞歸策略,它的技術(shù)出發(fā)點(diǎn)是Typelist,核心技術(shù)是:類(lèi)型推導(dǎo)、類(lèi)型萃取、特化/偏特化、多重繼承、類(lèi)型間去耦合,其成果是Loki庫(kù):對(duì)設(shè)計(jì)模式的封裝。
Typelist
是一種對(duì)類(lèi)型本身進(jìn)行存儲(chǔ)和管理的技巧,它的源碼已經(jīng)貼過(guò)了,我也作了注解,此處不再談?wù)摗?span lang="EN-US">
這是多重繼承在COM之后的又一大型運(yùn)用。多重繼承極易發(fā)生菱型缺陷,所以Loki庫(kù)使用了類(lèi)型間去耦合技術(shù)來(lái)避免:
??? template <typename T>
??? struct Type2Type
??? {
??????? typedef T OriginalType;
??? };
經(jīng)過(guò)這樣一層轉(zhuǎn)換后,原類(lèi)型
T
間的各種轉(zhuǎn)換關(guān)系(尤其是繼承
/
派生關(guān)系)已不復(fù)存在,
菱型缺陷
不會(huì)再發(fā)生了。
Loki庫(kù)的具體實(shí)現(xiàn)相當(dāng)講究技巧,設(shè)計(jì)它非常困難(難度遠(yuǎn)大于STL庫(kù),和Boost庫(kù)有得一拼啊)。但使用它卻非常容易,而且便利顯著。由于Loki庫(kù)提供了對(duì)設(shè)計(jì)模式的封裝,所以極大量地豐富了C++語(yǔ)言的表達(dá)能力,使的你的設(shè)計(jì)更容易地轉(zhuǎn)化為實(shí)現(xiàn)。
目前,Loki庫(kù)只提供了對(duì)廠模式和visitor模式的封裝,它還處于發(fā)展初期。
我以visitor模式為例,講解Loki庫(kù)提供的便利。
Visitor
模式有四種實(shí)現(xiàn)方式:1一串RTTI的類(lèi)型判斷;2二次調(diào)度(double
dispatch);3建立類(lèi)型與處理函數(shù)的對(duì)應(yīng)表;4非循環(huán)visitor(Acyclic Visitor)。在《More Effective
C++》 Item 31中討論了前3種實(shí)現(xiàn)(雖然它的例子本身不太算visitor模式的)。第四種方式在《使用設(shè)計(jì)模式改善程序結(jié)構(gòu)》(二)(
http://www-900.ibm.com/developerWorks/cn/java/l-dpstruct/part2/index.shtml
)中有詳細(xì)講解。
?
原型圖
以這張?jiān)蛨D而言,用戶(hù)需要自己實(shí)現(xiàn)大量的代碼,而且,由于使用多重繼承技術(shù),在具體
Host
類(lèi)間有繼承關(guān)系時(shí),它一定會(huì)發(fā)生問(wèn)題。
?Loki
庫(kù)實(shí)現(xiàn)圖
?
使用
Loki
庫(kù),用戶(hù)實(shí)現(xiàn)
visitor
模式時(shí)只需:讓
Host
類(lèi)從
BaseVisitable
繼承,并在所有派生類(lèi)中加上
DEFINE_VISITABLE()
宏,讓所有
Visitor
類(lèi)從
BaseVisitor
類(lèi)和
VisitorImpl
類(lèi)進(jìn)行二重繼承(并且可以只提供對(duì)自己感興趣的
Host
類(lèi)的處理函數(shù),不感興趣的不提供處理函數(shù))。用戶(hù)的工作量非常小、非常簡(jiǎn)單,設(shè)計(jì)人員可以不用為實(shí)現(xiàn)而分心了。
更重要的是,由于采用了類(lèi)型間去耦合技術(shù),多個(gè)
Host
之間存在繼承關(guān)系時(shí),不會(huì)發(fā)生問(wèn)題(其具體實(shí)現(xiàn)較復(fù)雜,于是我在
UML
圖上作了模糊處理,沒(méi)有展示出來(lái),留在以后
Loki
庫(kù)源碼讀解時(shí)講述)。