用C++語言編程就是用C++語言描述和表達周圍的現實世界。按照描述和表達現實世界的需要,本書共分為12章進行講解。第1~7章為結構化編程,第8~11章為類和對象編程,第12章為C++標準庫中的容器和算法框架。《C++面向對象程序設計實踐教程》并沒有羅列C++語言語法,而是通過實例仔細分析所有概念背后的基礎思想、原理和技術,使讀者從中獲得學習的樂趣。本書適合從未有過編程經驗但愿意努力學習程序設計的初學者。如果認真完成本書的學習,那么在程序設計領域已經有一個好的開始,可以寫相對簡單的程序,并能讀復雜的程序,為進一步的學習打下良好的理論和實踐基礎。
編寫背景
C++程序設計語言是由貝爾實驗室的Bjarne Stroustrup(本賈尼·斯特勞斯特盧普)于20世紀80年代開發的,是一門非常優秀且被廣泛應用的面向對象程序設計語言(Object-Oriented Programming Language),很多研究機構和公司都采用C++語言來開發各種高性能軟件。掌握了C++語言,就為編程入門和進階打下了牢固基礎。
興趣是最好的老師,因此,一本優秀的C++程序設計教材應該能夠激發讀者的學習興趣。本書并沒有羅列C++語言語法,而是通過實例仔細分析概念背后的基礎思想、原理和技術,讀者只有了解編程思想和原理后才能獲得學習的樂趣。而且隨著技術的發展,程序設計語言和編程工具會不斷演化甚至被取代,只有思想和原理才能保持其重要性。
本書適合那些沒有編程經驗但愿意努力學習程序設計的初學者,幫助他們理解程序設計的基本原理并獲得足夠多的經驗和實踐技巧,以便更好地利用C++程序設計語言進行編程工作。
學習建議
對于C++語言初學者的第一個建議就是要多做實踐練習。在這一點上,程序設計和其他需要實踐學習的技能是很相似的。比如,不可能只通過看書就學會烹飪、開車、游泳等技能,同樣,不動手編寫程序也不可能真正學會程序設計。本書給出了大量代碼實例,并配有詳細的文字說明和圖表,讀者可以通過讀寫這些代碼來理解程序設計的思想、概念和原理,并通過親身體驗編程中出現的錯誤,來理解C++語言的特性和語法規則。總之,在學習程序設計的過程中,不斷編寫代碼、發現錯誤并進行修改的實踐練習是不可替代的,而且,這也是學習的樂趣所在。
第二個建議是要有耐心。沒有人可以一蹴而就。學習任何一種重要、有價值的技能,都要花費一些時間,而這是值得的。C++語言包含的內容很多,語法規則紛繁復雜,各種新概念層出不窮。本書遵循循序漸進的學習規律,每一章都本著簡單實用的原則,介紹一些新的、有用的概念,并通過從實際應用中獲取的例子來闡述這些概念。本書不刻意探究C++語言的語法細節,也沒有重點介紹各種高深的編程技巧,而是從頭到尾、一章章地逐步推進,讀者通過程序代碼表達思想的能力會逐步提高,對C++語言的掌握程度也會越來越深入。當然,也要經常回頭對某些內容學習第二遍甚至第三遍,這是因為在遇到不理解的內容時,讀者很可能會快速掠過,導致一些知識斷層。本書每個章節的內容安排都假定讀者已經理解了之前學過的內容。
第三個建議是不要投入大量精力去探究語法或技術細節。熟記所有的C++數據類型及使用規則也許會使你考個高分或顯得很博學,但卻對提高程序設計能力沒有幫助,并且浪費了寶貴的時間和精力。就像很多人,即使有了漢英大字典,仍然不會寫英語作文一樣。最好的做法是盡量去理解程序背后的思想和原理,知道在什么情況下會遇到什么問題,應采用什么樣的解決方案,以及為什么這么做是最好的。
第四個建議是多與他人一起學習和討論問題。這是取得進步最直接也最有效的途徑。團隊討論會幫助你表達思想,測試你對問題的理解程度,并鞏固、加深學習記憶。本書中將有一個學習團隊(3個志同道合但性格各異的學生)來共同解決一個小型的家庭賬務管理項目。建議每個讀者都能加入一個團隊,進而參與到一個小型項目中。開發一個項目的過程,也就是編寫一個完整的有用程序的過程。大多數人都會在項目開發中對程序設計產生濃厚的興趣,進而學會如何把很多事情有效組織在一起。
最后一個建議是不要急切期盼“實際的”例子。本書中的每個實例都能直接說明一種語言特性或一個概念,而很多現實世界中的實例過于凌亂,所能展示的知識也不如書中的實例多。數十萬行代碼的商業程序中所采用的技術在書中用幾行或幾十行代碼的程序同樣能展現出來。最好的理解現實世界的途徑就是好好研究一些基礎小程序。記住:麻雀雖小,五臟俱全。
如果讀者能認真完成本書的學習,可以期待已經在程序設計領域有了一個好的開始,可以編寫相對簡單的程序,并能讀懂復雜的程序,且為進一步學習打下良好的理論和實踐基礎。
本書特色
1. 每章都包含“本章要點”和“本章小結”部分,以幫助讀者明確全章的學習內容。
2. 部分章包含星號標記的選讀小節,這部分內容可以跳過而不會影響全書的連貫性,它們是為那些自學能力強且渴望挑戰的學生準備的。
3. 課后的練習題包括填空題、簡答題、編程題和獨具匠心的提升練習。提升練習部分均為生活中的實際課題,如環境污染、中國人健康指數計算、人口增長、計算機輔助教學、民意測評等,其中的部分內容在前后章節中具有一定的延續性。
4. 本書的配套資料包含課件、實例源代碼、部分練習題及編程練習答案。書中的源代碼可以自由修改、編譯,以符合自己的需要。
5. 本書按照讀者在學習程序設計中遇到的問題來組織內容,隨著讀者對程序設計的理解和實際動手能力的提高,一個主題一個主題地平滑向前推進。本書的敘述順序更像一部小說,而不是一部字典。
6. 本書每個知識點和技術要點都給出了典型實例和代碼分析,這些代碼不僅能夠一針見血地指明技術要點的本質,而且短小精煉,方便讀者自行嘗試。
7. 本書以一個家庭賬務管理系統項目案例貫穿始終,第2~6章、第8章、第9章和第12章的最后一節都是本項目部分功能的實現。每章中的知識點則使用獨立的例子,并輔以實例輸出和代碼分析,以闡述該章介紹的主題,并在討論主題的過程中逐步解決這個案例。
8. 本書虛擬了幾個人物,在每章最后通過一些有趣的對話,總結C++語言正確的學習方法。通過一些錯誤的例子和實際的錯誤代碼來進行改正,這是本教材的一大特色。
內容摘要
用C++語言編程,本質上就是用C++語言描述和表達周圍的現實世界。按照描述和表達現實世界的需要,本書可以簡單地分為3個部分:結構化編程、面向對象的編程和標準庫編程。
結構化編程部分簡要介紹C++語言的發展和特點、標準庫的知識、基本數據類型、分支和循環控制結構、基本過程化單元——函數的定義和使用方法,以及數組和指針的實現和使用。通過基本數據類型學習,讀者將學會使用int、double、string等數據類型來描述現實世界中的數據;通過邏輯控制語句學習,讀者將學會使用if-else來控制程序邏輯;通過函數學習,讀者將學會使用函數來表達完整的算法。
面向對象編程部分重點討論了類和對象、組合和繼承、多態與虛擬函數、運算符重載和泛型程序設計等內容,以循序漸進的方式介紹封裝(Encapsulation)、繼承(Inheritance)和多態(Polymorphism)這3種面向對象語言的主要技術。本部分中,借助許多有意義的范例程序,將講解抽象化、派生類所定義對象的構造和析構次序、混合組合和繼承以建立新的類、重載虛擬函數、虛擬析構函數等被大部分C++書籍忽略的內容。面向對象的思想將幫助讀者抽象現實世界,而類和對象則幫助讀者將抽象的結果在程序中表達出來。
標準庫編程部分關注標準庫中的容器和算法框架。泛型程序設計就是將程序寫得盡可能通用,簡單而優雅,同時不損失效率。本部分展示了C++標準模板庫STL中的容器(如向量)是如何實現的,以及如何使用它們,還展示了常見的標準庫算法(如查找、排序等);簡要介紹了一些概念、術語及主要組件的使用方法,目的是使讀者對STL與泛型程序設計有一個概要性的了解。
上述內容都是C++語言中最基本又最實用的部分,通過對這些內容的學習,讀者完全可以自如地用C++語言來描述和表達現實世界。
建議和反饋
沒有絕對完美的教材(因為每個人的需求和評價角度總是差別很大),但我們會盡力使本書的內容及其支持材料接近于完美。脫離讀者是不可能寫出好教材的,為此我們需要大家的反饋。歡迎廣大讀者對本書的內容、結構、案例等提出反饋意見,以使我們在下一版中能及時做出更正、補充或修改。讀者在學習過程中如果有什么疑問或對本書有任何建議,可通過發送電子郵件(lcrlj@126.com)與我們聯系。
作者分工
本書第1~6章由吳迪編寫,第7章和第12章由魏連鎖編寫,第8~11章由李長榮編寫,各章的家庭賬務管理系統案例由李長榮編寫,全書例題由吳迪和魏連鎖調試通過。課題組老師也參與了部分內容的編寫工作。
第1章 C++語言概述1
1.1 為什么要學習程序設計1
1.2 C++語言歷史2
1.3 C++語言特點3
1.4 C++語言程序設計風格4
1.4.1 結構化程序設計4
1.4.2 面向對象程序設計5
1.4.3 泛型程序設計7
1.5 標準庫8
1.5.1 標準庫簡介8
1.5.2 標準模板庫8
習題10
第2章 第一個C++程序13
2.1 程序13
2.2 入門實例14
2.3 實例分析15
2.3.1 注釋15
2.3.2 使用空白字符16
2.3.3 包含其他文件16
2.3.4 命名空間17
2.3.5 定義main()函數18
2.3.6 使用標準輸入和輸出18
2.3.7 字符串20
2.3.8 語句的終止20
2.3.9 從main()函數返回值20
2.4 編譯C++語言程序21
2.5 鏈接23
2.6 編程環境23
2.7 家庭賬務管理系統——啟動界面24
習題26
第3章 數據類型29
3.1 數據類型29
3.1.1 整數類型31
3.1.2 浮點類型33
3.1.3 字符類型34
3.1.4 布爾類型35
3.1.5 空類型35
3.1.6 枚舉類型35
3.2 關鍵字36
3.3 常量36
3.3.1 什么是常量36
3.3.2 為什么需要常量37
3.3.3 使用常量37
3.4 變量38
3.4.1 什么是變量38
3.4.2 變量的定義39
3.4.3 變量的命名39
3.4.4 變量的賦值40
3.5 結構體42
3.5.1 結構體類型的定義和初始化42
3.5.2 結構體變量的使用43
3.6 家庭賬務管理系統——用戶信息45
習題48
第4章 控制語句51
4.1 控制結構52
4.2 選擇語句52
4.2.1 布爾表達式和關系運算符53
4.2.2 單路選擇if語句54
4.2.3 雙路選擇if語句55
4.2.4 多路選擇if語句56
4.2.5 switch選擇語句58
4.2.6 選擇結構的條件表達式62
4.3 循環語句63
4.3.1 for循環64
4.3.2 for循環的嵌套66
4.3.3 無限循環68
4.3.4 while循環語句69
4.3.5 do-while循環語句71
4.3.6 幾種循環方式的比較72
4.4 轉向語句73
4.4.1 break語句73
4.4.2 continue語句73
4.4.3 goto語句74
4.5 家庭賬務管理系統——主菜單76
習題79
第5章 函數81
5.1 函數簡介81
5.2 C++程序組件82
5.3 函數命名83
5.4 void函數的聲明、定義和調用83
5.5 返回值函數86
5.6 參數傳遞88
5.6.1 形參和實參89
5.6.2 向函數傳遞參數89
5.6.3 值傳遞和引用傳遞90
5.6.4 傳遞多個參數93
5.7 內聯函數95
5.8 函數重載96
5.9 家庭賬務管理系統——設置窗口標題函數97
習題100
第6章 數組與字符串103
6.1 數組的概念103
6.2 數組的聲明104
6.3 數組的初始化107
6.4 數組作為函數的參數111
6.5 二維數組的聲明與初始化114
6.6 二維數組作為函數參數117
6.7 字符串119
6.7.1 類C字符串120
6.7.2 string字符串122
6.8 家庭賬務管理系統的系統登錄123
習題128
第7章 指針130
7.1 指針的概念130
7.2 變量與指針131
7.3 數組與指針134
7.4 指針與引用137
7.5 函數與指針138
7.5.1 作為函數參數的指針138
7.5.2 函數指針139
7.5.3 指針函數141
7.6 使用const修飾指針143
7.7 動態內存分配146
7.8 鏈表149
習題153
第8章 類和對象155
8.1 面向過程程序設計和面向對象程序設計156
8.2 類和對象的關系156
8.3 聲明類類型157
8.3.1 使用struct聲明類和使用class聲明類157
8.3.2 對類的成員進行訪問159
8.3.3 類的get和set方法159
8.4 類的成員函數162
8.4.1 成員函數的性質162
8.4.2 在類外定義成員函數162
8.4.3 inline成員函數164
8.5 類聲明與成員函數定義分離165
8.6 構造函數168
8.6.1 什么是構造函數168
8.6.2 對象的初始化168
8.6.3 構造函數的作用169
8.6.4 帶參數的構造函數171
8.6.5 用參數初始化表對數據成員初始化172
8.6.6 構造函數的重載173
8.6.7 使用默認參數值的構造函數174
8.7 析構函數176
8.8 公有數據的保護179
8.8.1 常對象成員179
8.8.2 常對象182
8.9 靜態成員184
8.9.1 靜態數據成員184
8.9.2 靜態成員函數186
8.10 示例程序:時間標記類188
8.11 家庭賬務管理系統——用戶實體類192
習題199
第9章 繼承與派生202
9.1 繼承和派生的概念202
9.2 派生類的聲明方式204
9.3 派生類的繼承方式206
9.4 派生類的構造函數和析構函數207
9.4.1 派生類的構造函數207
9.4.2 派生類的析構函數209
9.5 使用繼承必須滿足的邏輯關系211
9.6 繼承在軟件開發中的重要意義212
9.7 家庭賬務管理系統——添加賬目及賬目查詢213
習題219
第10章 多態性和虛函數221
10.1 多態性的概念221
10.2 虛函數222
10.2.1 虛函數的作用222
10.2.2 運行期綁定和編譯期綁定225
10.2.3 虛函數使用方法226
10.2.4 構造函數與析構函數227
10.2.5 什么情況下聲明虛函數229
10.3 純虛函數和抽象類230
10.3.1 純虛函數230
10.3.2 抽象類233
習題236
第11章 運算符重載238
11.1 運算符重載的概念238
11.2 運算符重載的方法240
11.3 基本運算符重載243
11.4 友元函數244
11.5 賦值運算符重載246
11.6 輸入與輸出運算符的重載249
11.7 特殊運算符的重載251
11.7.1 下標運算符的重載251
11.7.2 自增與自減運算符的重載254
11.7.3 類型轉換運算符的重載256
習題260
第12章 模板與STL261
12.1 為什么使用模板261
12.2 函數模板263
12.3 類模板267
12.4 STL271
12.4.1 STL的組成272
12.4.2 在程序中使用STL273
12.5 容器276
12.5.1 vector容器277
12.5.2 list容器280
12.5.3 set容器283
12.5.4 map容器285
12.6 算法287
12.6.1 非變序型算法287
12.6.2 變序型算法289
12.6.3 排序算法291
12.6.4 數值算法294
12.7 家庭賬務管理系統——STL的應用295
12.7.1 STL的vector的應用295
12.7.2 用戶賬目信息及個人信息的持久化保存297
習題301