2011年11月21日 星期一

Effective C++ item 23: 以 non-member、non-friend 取代 member function

看到這條款有種水到渠成的快感, 來寫下心得。

在我大學寫 Java 四年的時光裡, 我寫了一堆 over design 假 OOP 的東西。於是, 在我出社會工作的三年裡, 我改用 Python 盡可能的都寫成 function, 覺得很卡時 (像是一堆參數重覆傳來傳去), 才會包成 class。想體會看看兩種極端的寫法, 藉此看看能否從中悟出什麼道理。

這七年的時光合起來, 我沒悟出什麼大道理, 到是覺得後來這種寫法偶而是有點不便, 不過大部份時候還挺順的, 不會包得太笨重。直到看到 Effective C++ item 23, 才有種恍然大悟的感覺, 明白背後的原因。

作者提出一個觀點: 愈少程式能動到資料, 封裝的效果愈好。所以, 若這個操作可以寫成 non-member、non-friend function, 可保證它不能存取到 private data。再者, 也比較有機會讓不同 class 來重用這個 function。像是 std 裡面的 sort(), 就比放到 vector 裡成為 member function 來得好。既可提高 vector 的封裝效果, 也方便重用 sort (有提供 index 和 comparable 即可)。這篇兼顧「減少相依性」和「提高重用性」切入說明這則條款的精髓, 值得一讀。

初看這個觀點有些反直覺, 還是會覺得放到 class 裡比較像「封裝」。要找函式時也比較方便, 看 class 的 header 就可知道全部操作。但 item 23 接著強調: 若要方便找函式, 放在 namespace 下也有類似的效果, 如同 Java 寫成 utility class 的 static member function 一樣。

回想 Java 的 Arrays.sort() 和 Collections.sort() 也是同樣的設計, 只是 Java 沒 namespace, 這類函式改放到某個 class 下。當然, Python 的 sorted() 也是如此, 不過是放在 __builtin__ 這個 package 裡。其它類型的還有 max()、min() 等函式。Python 和 Java 都有提供方便的 max()、min() 來操作 container, 不知 C++ 有沒有類似的東西, 只看到 algorithm 有比較兩個數字的實作。

2011-11-22 Update

Aethanyc 提醒, STL 裡有 max_element()

沒有留言:

張貼留言

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...