想寫點《C++ Primer》的學習心得。心得不同於筆記,筆記往往較為詳細,並設計到具體的一些實現知識點。而心得主要指自己思考後的所得,側重於對語言整體的理解。心得分兩部分:先“糾正”自己的一點兒錯誤的認識【加引號是因為自己糾正過的不一定就是正確的】;再簡略說說自己對物件導向的一點理解。作為筆記分享出來,當然是希望能夠與大家共同交流。自身水平目前僅在這個層,聞道有先後,呵呵。如果路過的朋友有話想說,還望不吝賜教。
一點兒認識:
1)舊版基於以前微薄的基礎,我覺得一門語言【註:此處指電腦程式設計語言】應該有著自身的文法和應用體系,以與其他的語言之間互相區別。以為這門語言既然誕生了,那麼就意味著現實中已經對它存在著足量的需求,並且它所擁有的特性也是滿足這些需求的。而一門已經存在的語言能夠經過改進以適應這些新的需求,那麼它便不會更名易幟。所以在聲明用門語言來開發相關的應用的時候應該僅使用這門語言相關的東西即可,不應該互相摻和【混合編程不在此範圍】。這裡繞了一個彎,其實我想說的是C和C++。因為看過一些C++的程式【可能還不夠多,不過夠說明我想要說明的東西了】,但我常常在這C++工程的代碼中發現很多C中的庫函數、結構體的使用。在我看來,既然C++是一門新的語言,那麼用C++時就應該用C++中的那些東西;既然C++如此強調類的使用,那麼C中的結構體的使用就應該儘可能的避免而使用類來進行設計。最近因為要用C++寫幾段小程式,所以我一直很刻意:在設計到資料結構的定義、函數庫的使用的時候,就全部使用C++中的相關resource。所以在設計資料結構時便不考慮C中常用的結構體,在用檔案讀取等操作時全用C++中的相關類。其中發現兩個問題,一是程式不夠靈活,在進行大量資料運算時覺得會影響效率,因為其資料往往儲存在類中,那麼對類的訪問必然會增加額外的時間開銷【這裡要throw一個問題:怎麼去衡量段代碼的效率,比如用類和用結構體相比(猜測用類肯定更為耗時,但如何證明呢?)】。二是程式不可避免的要使用到一些數學庫,而一些常用的數學函數庫在C的標準庫中已存在,所以要用到它們。這就迫使自己去檢測自己的認識,是不是真的是自己所想的那樣? 2)更新版在查閱資料時,C++ Reference 對庫的分類對我有了點兒新的啟示。其中,對C++庫的分類有如下關係:
C++
庫
= C
庫
+ C++
標準庫
C++
標準庫
=
輸入輸出庫
+ STL +
其他少數幾個庫 即C中的標準函數庫也是C++的一部分,所以之前的想法是錯的。那麼為什麼會那樣用呢,一個原因可能是因為一些C中的庫的使用看起來依然是不可避免的(數學庫)。二個原因可能是在 C與C++中交集部分進行選用時,可以偏重更為效率的使用方式,如檔案的讀取,用C中的檔案讀取函數與C++中的檔案讀取類進行比較,誰快?另外一個原因可能是因為習慣問題。之前雖然聽說C++是進階版的C,但那也只把重心位移到“進階”二字,而沒有同等的看待其中的“C”,它們之間的關係沒怎麼分清楚,只知道有差別,不知道差在哪裡,聯絡又在哪些地方。所以感覺是沒有這次來得深的。
一點兒理解: 物件導向的流行主要在於一種合乎人們思考習慣的思維方法。物件導向的世界主要是由各種對象組成的,這裡說是由各種對象而沒說各種類主要是基於我們通常只是對這個世界中的對象感興趣。這個世界上的各種活動主要【是主要,想象下類的靜態成員】是通過對這些對象的操作(訪問、相互之間的互動)來完成的。而其中的類看上去只是一些抽象的實體,實際上
極少參與活動。 在進行需求分析時,我們往往會先從某個對象開始分析,我們需要它哪些功能,即需要提供哪些介面,又需要哪些屬性【對象的形成】。向上進行抽象,如果有多個對象,那麼能否抽象出它們共同的部分然後再進行派生呢【類的形成】。如果可以,繼續向上進行抽象,看能否得到各種類之間的相似部分【類模板】…從而構成一個類的體系。 1)類 書中有這麼一段話:
“ Classes are the most important feature in C++. Early versions of the language were named "C with Classes," emphasizing the central role of the class facility. As the language evolved, support for building classes increased. A primary goal of the language design has been to provide features that allow programmers to define their own types that are as easy and intuitive to use as the built-in types. This chapter presents many of the basic features of classes.
” 我們在使用一些整形、浮點型進行運算的時候感覺很直觀,這些類型的一些計算屬性是我們非常熟悉的。那麼在定義出新的資料結構的時候,能不能讓它們也具有相類似的屬性,讓這些新的資料結構本身及其它們之間的關係也變得這麼容易呢。這是一個很好的注意,所以C++便提供了這些特性,讓我們可以定義一些我們需要的類,並對其進行封裝、介面設計來達到我們任性的要求。而物件導向中的“抽象”屬性【繼承、泛型】往往能夠讓一個大型整個工程的結構變得更清晰,實現起來更效率。 可窺知,物件導向的程式設計主要為減輕程式設計負擔,讓程式員從繁雜的資料和邏輯中脫離出來。其中很重要的一點是其代碼的可重用好,不難明白,在進行GUI開發的時候通常都是基於一些物件導向的設計。 2)異常處理機制 這些天讀了一些程式,發現程式中極少使用C++的異常處理機制,是因為效率原因還是因為程式員習慣的疏漏?當然,可能因為我看的這些程式僅是一些非商業化的程式,比如程式只用來當教程或者示範準系統使用,可以不用考慮高可靠性。對於一些初級教程這是可以理解的,畢竟如果開始便加入這些東西只會增加其理解難度。而對於一些已經作為一個微型工程在進行構建的代碼,我更願意把它看作一種習慣式的編程風格,也即,好的編程風格應該考慮到這些異常。粗略看起來,使用異常處理機制往往很繁瑣,因為首先要考慮到儘可能多的異常情況,然後再添加相應的處理代碼。其實,用好異常處理機制往往能夠使程式在具有高可靠性的同時,還能夠縮減一些重複的判斷代碼。比如,在一段代碼塊中,你可能對針對多處具有明顯異常的地方分別進行處理,但用異常捕獲機制先對這些異常進行分類,再分別針對各種類型的異常對象進行處理。 3)命名空間 又一個最佳化程式管理,提升開發效率的特性。不多說了,書看了就能懂,懂了就能用;不用的話看了也沒用,懂了也會易忘掉。並且一般在比較大的工程中才能用到。
本筆記的幾句話也沒說多少東西,只是自己突然感覺更新的認識,一時激動,想寫出來。自己也在想,要不要等把所有的章節看完後再寫。不過基於兩點考慮,還是覺得先寫下來好,即使寫得不是很對。一是一本書往往比較多,看完要花費一些時日,周期偏長。這對一部分人來說往往是件挺奢侈的事情。二是在看的過程中如果太注重是否“看完”往往會忽略掉看書過程當中的一些小的問題,有時候你即使記下這些問題,等看完之後來整理往往沒有了當初那個勁頭而不能很好的完成。這就像有時候我們突然很想做一件事情,但因為一些習慣而拖到之後再去完成,等到之後時,要麼沒有了當初那個熱情而放棄,要麼再之後直到沒有下文。 所以,自己覺得。對於一本書不論看了多少,如果覺得有了點感覺,那麼就應該寫下來,這樣有所思考的學,感覺會好一些。
更新(2010.7.29):
【類】
經朋友(感謝小唐)提醒, 在“類”中這一部分有個概念有誤,即我將泛型歸划到物件導向的範疇。物件導向和泛型其實只是兩個東西,物件導向側重資料抽象,定義不同的資料類型。而泛型側重念抽象,將一些演算法泛化到各種泛型容器上。在這裡(即C++中)STL即是泛型的一種實現,裡面定義的一些容器能夠很好的使用泛型演算法。更為詳細的文章可以參見這裡。
【異常處理機制】
關於C++中異常處理的一點兒討論可參加這裡,如果覺得文章比較長可以參加這裡詳細的機制分析。
【本筆記的幾句話】
當然,不僅僅該寫下來,還應該有勇氣分享出來。這樣便可和朋友們進行一些討論或者爭論,也會有不小的收穫。
更新(2010.8.13):
【異常處理機制】
有關異常處理與錯誤處理的比較,見這裡。基於一些主觀原因,目前這些都是支援異常處理的,但這並不表示它一定就是完美的。