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