基本信息
作者:羅劍鋒
出版社:電子工業出版社
ISBN:9787121115776
出版日期:2010 年9月
開本:16開
頁碼:578
版次:1-1
編輯推薦
站在C++98的最高峰迎接C++0x的曙光
深入C++“準”標準庫,Boost你的力量
內容簡介
boost是一個功能強大、構造精巧、跨平台、開源並且完全免費的c++程式庫,有著“c++‘準’標準庫”的美譽。
它由c++標準委員會部分成員所設立的boost社區開發並維護,使用了許多現代c++編程技術,內容涵蓋字元串處理、正則表達式、容器與數據結構、並發編程、函式式編程、泛型編程、設計模式實現等許多領域,極大地豐富了c++的功能和表現力,能夠使c++軟體開發更加簡潔、優雅、靈活和高效。
本書基於boost1.42版,介紹了其中的所有99個庫,並且詳細深入地講解了其中數十個庫,同時實現了若干頗具實用價值的工具類和函式,可幫助讀者迅速理解掌握boost的用法以及套用於實際的開發工作中。
本書內容豐富、結構嚴謹、詳略得當、講解透徹,帶領讀者領略了c++的最新前沿技術,相信會是每位c++程式設計師的必備工具書。
目錄
第0章 導讀
第1章 boost程式庫總論
第2章 時間與日期
第3章 記憶體管理
第4章 實用工具
第5章 字元串與文本處理
第6章 正確性與測試
第7章 容器與數據結構
第8章 算法
第9章 數學與數字
第10章 作業系統相關
第11章 函式與回調
第12章 並發編程
第13章 程式語言支持
第14章 其他boost組件
第15章 boost與設計模式
第16章 結束語
附錄a 推薦書目
附錄b 網路資源
附錄c c++標準簡述
附錄d stl簡述
附錄e ref_array實現代碼
前言
屈指算來,接觸C++語言至今已經有十餘個年頭了。回首往事,不禁感慨良多。
緣起
1996年我上大學最開始學的是Pascal,不得不說,Pascal嚴謹的程式風格確實很適合作為一門教學語言,然而用於實際開發就不那么合適了(直到出現Delphi)。由於當時學校並未開設C語言課程,因此在Pascal課程結束後我就買書自學C/C++語言,並在次年報名國家計算機水平考試,靠著一點點編程和考試的“天分”獲得了高級程式設計師資質(當年很熱衷考級考證,後來就“淡定”多了)。雖然有了資格證,但我仍然算是個C++的初學者,對於C++的認識還處於C的面向過程和簡單的基於對象層次上。
新千年伊始我考入了北京理工大學就讀研究生,因為跟導師做項目開始接觸STL與C++標準庫,大概是2005年從1 33版結識了Boost,這才真正領略了C++的精髓。那段時期Java和C#正在國內大行其道,C++則勢單力薄,有關STL和C++標準的技術書籍寥寥無幾,而講解Boost的書更是為零,故對Boost的學習基本只能靠自己的摸索與實踐。好在Boost自帶的文檔相當豐富(雖然看全英文的資料十分辛苦),而且源碼也寫得比較清晰規範,在熟悉了STL的基礎上學習Boost倒也並不算太難。
但Boost的一個最大的特點就是“龐大”,功能組件眾多,要想把它全部裝進腦子裡融會貫通基本上是不可能的,使用時需要經常查閱英文文檔,相當的麻煩。因此,在學習的過程中,我逐漸產生了編寫學習筆記的想法。一開始只是一個簡單的純文本檔案,記錄了一些使用經驗的片斷,隨著積累的不斷增加,純文本形式已經不能夠滿足知識整理的需求了,於是我又把這些文字遷移到了Word文檔里,把使用經驗分類編目,加以較系統地歸納梳理。慢慢地,這份學習筆記居然有了上萬字的規模,成為了一份很好的Boost備忘參考,在日常的開發工作中給了我很大的幫助——就像《設計模式》一書中所說的那樣,捕獲了很多使用Boost解決問題的實踐經驗,避免了重複發現。不過,這份資料一直是僅限於我個人使用,屬於“自娛自樂”的作品,從未示人。
時間一晃到了2010年1月份的某天夜裡,不知道是什麼原因我忽然失眠了,躺在床上翻來覆去怎么也睡不著。突然,一個念頭闖入了腦海:把Boost開發經驗整理出版吧,讓更多人能夠分享這些知識,正所謂“獨樂樂,與眾樂樂,孰樂?”。這個大膽的想法的出現讓我那天的失眠又延長了幾個小時——關於書的各種構想在頭腦中“肆虐橫行”。
隨後的幾天裡我就把這個想法付諸行動了,雖然以前也寫過並發表很多文章,也在網上印刷了幾本個人文集,但出版正式的書還是第一次。在把學習筆記進一步整理完善,編寫出較完整的結構和一個樣章後,我就開始聯繫出版社了。當初並沒有多大的信心,畢竟我這個作者名不見經傳,也沒有什麼資歷、背景和名氣(而且還是個“網盲”,從未跟隨潮流開個人部落格)。很幸運,發出的第一個E-mail就是電子工業出版社,而且編輯也在第一時間回復了我,這才給了我以持續寫作完成全書的動力。
寫作過程中我也進一步加深了對Boost的認識,澄清了許多原來未曾注意到的細節。原本只打算寫20萬字左右、三百多頁,但寫到中途才發現Boost庫的博大精深遠非當初的理解,也意識到了自己當初學習的膚淺。歷經了近半年近乎不眠不休的努力,最終呈現給讀者的是這本厚達500多頁的圖書,文字量是最初學習筆記的數十倍,內容也翔實豐滿了很多——達成這個結果,我個人可以說是問心無愧了。
C++與Boost
C++較Java和C#等語言的一個最大不同在於它並非是由某個公司或個人把持的,它的真正發展動力來自於廣大程式設計師。Boost就是這樣的一個典範,它成功地填補了從C++98到C++0x這“失落的十年”間的空白,在競爭對手Java和C#不斷更新版本新增特性的時候以庫的形式極大地增強了C++的能力,使C++不至於因為標準規範的滯後而落後於時代,而且Boost還深層次挖掘了C++的潛力,開創了泛型編程、模板元編程、函式式編程等嶄新的境界。
就個人來說,我比較喜歡的Boost版本有兩個,分別是1 35和1 39:1 35版增加了asio、bimap、circular_buffer等許多重要組件,而1 39版則增加了signals2庫,這兩個版本都在我的工作用機上停留了相當長的時間。落筆之時,Boost已經更新到了1 43版,成長為了一個相當完善、全面、強大的C++程式庫。可以毫不誇張地說,現在的C++程式設計師,如果不熟悉Boost,那么至少喪失了一半使用C++的好處,同時會多耗費數倍的開發精力和時間。
隨著C++0x標準的即將來臨,Boost程式庫的發展也出現了加速的趨勢,由原來間隔數月不定期更新版本,改為定期(每3個月左右)發布新版本,而且每個新版本都會包含大量極有價值的更新內容。因此,希望讀者在閱讀本書時及時訪問Boost的官網,以便獲取最新的版本。
感謝讀者選擇本書,再說一句真心的“套話”(笑):限於作者水平有限,書中錯漏在所難免,敬請讀者原諒、指正。
首先我要感謝整個C++群體,特別是:C++語言的發明者Bjarne Stroustrup博士——他給我們帶來了美妙的C++;然後是Alexander Stepanov和C++標準委員會——他們把STL引入了C++,開創了C++的現代編程風格;以及Beman G Dawes、Boost程式庫的所有作者和Boost社區——他們為我們奉獻了如此高水準的程式庫。
其次我要感謝電子工業出版社博文視點公司,他們給了我這個把自己的開發經驗出版成書的機會,在把潦草的個人學習筆記變成正式圖書的過程中他們付出了艱辛的努力。還要感謝陳碩先生,他審閱了本書的部分手稿,提出了很多有價值的參考意見,並慨然為本書撰寫序言。
接下來我要感謝我的家人:感謝我的父母和弟弟,他們永遠是我生命中最重要的人;感謝我的妻子,她自始至終都支持我的寫作,並擔負了大部分照顧孩子的家務(雖然偶有怨言);還要對已滿一歲半的女兒說聲抱歉,為了寫作本書,我已經犧牲了很多陪她玩耍的時間。
我還要感謝黃美華、馮薇、戚天龍、羅玉震、顏靜、陳剛、張秋香、繆澤波等同事,長期的共事令我們建立了深厚的友誼。對後兩位同事致以特別的感謝,他們對完成本書提供了大力的支持和幫助。
最後,感謝多年以來的好友岳大海、時吉斌、王峰,感謝我的中學老師鄧英、杜愛芹、練鑫雲、陳靜,感謝我的研究生導師賈雲得,以及所有在我成長過程中曾經給予我關心和幫助的朋友們!
序言
最近一年我電話面試了數十位 C++ 應聘者,慣用的暖場問題是“工作中使用過 STL 的哪些組件?使用過 Boost 的哪些組件?”。得到的答案大多集中在 vector、map 和 shared_ptr。如果對方是在校學生,我一般會問問 vector 或 map 的內部實現、各種操作的複雜度以及疊代器失效的可能場景。如果是有經驗的程式設計師,我還會追問 shared_ptr 的執行緒安全性、循環引用的後果及如何避免、weak_ptr 的作用等。如果這些都回答得不錯,進一步還可以問問如何實現執行緒安全的引用計數,如何定製刪除動作等等。這些問題讓我能迅速辨別對方的 C++ 水平。
我之所以在面試時問到 Boost,是因為其中的許多組件確實可以用於編寫可維護的產品代碼。Boost 包含近百個程式庫,其中不乏具有工程實用價值的佳品。每個人口味與技術背景不一樣,對 Boost 的取捨也不一樣。就我的個人經驗而言,首先可以使用絕對無害的庫,例如 noncopyable、scoped_ptr、static_assert 等,這些庫的學習和使用都比較簡單,容易入手。其次,有些功能自己實現起來並不困難,正好 Boost 里提供了現成的代碼,那就不妨一用,比如date_time 和 circular_buffer 等。然後,在新項目中,對於訊息傳遞和資源管理可以考慮採用更加現代的方式,例如用 function/bind 在某些情況下代替虛函式作為庫的回調接口、藉助shared_ptr實現執行緒安全的對象回調等等。這二者會影響整個程式的設計思路與風格,需要通盤考慮,如果正確使用智慧型指針,在現代 C++ 程式里一般不需要出現 delete 語句。最後,對某些性能不佳的庫保持警惕,比如 lexical_cast。總之,在項目組成員人人都能理解並運用的基礎上,適當引入現成的 Boost 組件,以減少重複勞動,提高生產力。
Boost 是一個寶庫,其中既有可以直接拿來用的代碼,也有值得借鑑的設計思路。試舉一例:正則表達式庫 RegEx 對執行緒安全的處理。
早期的 RegEx 類不是執行緒安全的,它把“正則表達式”和“匹配動作”放到了一個類裡邊。由於有可變數據,RegEx 的對象不能跨執行緒使用。如今的 regex 明確地區分了不可變(immutable)與可變(mutable)的數據,前者可以安全地跨執行緒共享,後者則不行。比如正則表達式本身(basic_regex)與一次匹配的結果(match_results)是不可變的;而匹配動作本身(match_regex)涉及狀態更新,是可變的,於是用可重入的函式將其封裝起來,不讓這些數據泄露給別的執行緒。正是由於做了這樣合理的區分,regex 在正常使用時就不必加鎖。
Donald Knuth 在“Coders at Work”一書里表達了這樣一個觀點:如果程式設計師的工作就是擺弄參數去調用現成的庫,而不知道這些庫是如何實現的,那么這份職業就沒啥樂趣可言。換句話說,固然我們強調工作中不要重新發明輪子,但是作為一個合格的程式設計師,應該具備自製輪子的能力。非不能也,是不為也。
C/C++ 語言的一大特點是其標準庫可以用語言自身實現。C 標準庫的 strlen、strcpy、strcmp 系列函式是教學與練習的好題材,C++ 標準庫的 complex、string、vector 則是類、資源管理、模板編程的絕佳示範。在深入了解 STL 的實現之後,運用 STL 自然手到擒來,並能自動避免一些錯誤和低效的用法。
對於 Boost 也是如此,為了消除使用時的疑慮,為了用得更順手,有時我們需要適當了解其內部實現,甚至編寫簡化版用作對比驗證。但是由於 Boost 代碼用到了日常應用程式開發中不常見的高級語法和技巧,並且為了跨多個平台和編譯器而大量使用了預處理宏,閱讀 Boost 源碼並不輕鬆愜意,需要下一番功夫。另一方面,如果沉迷於這些有趣的底層細節而忘了原本要解決什麼問題,恐怕就捨本逐末了。
Boost 中的很多庫是按泛型編程的範式來設計的,對於熟悉面向對象編程的人而言,或許面臨一個思路的轉變。比如,你得熟悉泛型編程的那套術語,如concept、model、refinement,才容易讀懂 Boost Threads 的文檔中關於各種鎖的描述。我想,對於熟悉 STL 設計理念的人而言,這不是什麼大問題。
在某些領域,Boost 不是唯一的選擇,也不一定是最好的選擇。比如,要生成公式化的原始碼,我會首選用腳本語言寫一小段代碼生成程式,而不用 Boost Preprocessor;要在 C++ 程式中嵌入領域特定語言,我會首選用 lua 或其他語言解釋器,而不用 Boost Proto;要用 C++ 程式解析上下文無關文法,我會首選用 ANTLR 來定義詞法與語法規則並生成解析器(parser),而不用 Boost Spirit。總之,使用 Boost 時心態要平和,別較勁去改造 C++ 語言。把它有助於提高生產力的那部分功能充分發揮出來,讓項目從中受益才是關鍵。
要學習 Boost,除了閱讀其官方網站的文檔、示例與源碼之外,最好能有一本比較全面的中文書在手邊隨時翻閱。對於不諳英文的開發者,這更是可幸之至。您手上這本《Boost 程式庫完全開發指南》是很好的使用指南與參考手冊。作者由淺入深地介紹了 Boost 的大部分常用內容,能讓讀者迅速了解 Boost,並從中找到自己需要的部分。拿到這本書稿之後,我有粗有細地閱讀了一遍,總體來看,作者水平很高,也相當務實,對 C++ 和 Boost 的理解與運用很到位,我從這本書學到了不少新知識。為此,我樂於向希望學習 Boost 程式庫的開發者推薦這本靠譜的書。
須知“功不唐捐”,作為一名現代 C++ 程式設計師,在 Boost 上投入的精力定能獲得回報。