深度探索C++對(duì)象模型(1)

字號(hào):

第一章:關(guān)于對(duì)象(Object Lessons)
     讀完這一章使我想到了一個(gè)很久以前看到的一個(gè)笑話(huà),編寫(xiě)一個(gè)HELLO WORLD的程序,隨著水平和職務(wù)的不一樣,程序代碼也隨著變化。當(dāng)初看時(shí)完全當(dāng)作笑話(huà)來(lái)看,現(xiàn)在看來(lái)寫(xiě)此笑話(huà)的人水平不一般。如果要使你的代碼能夠限度的適應(yīng)不同的運(yùn)行環(huán)境,和限度的復(fù)用,則在設(shè)計(jì)和編寫(xiě)的過(guò)程中需要考慮的問(wèn)題很多,因此代碼已變的不在具有C語(yǔ)言的簡(jiǎn)潔,高效。而犧牲了這些優(yōu)勢(shì)換來(lái)的是更好的封裝。當(dāng)然如果你只是要打印Hello World則不必這樣做了。
     以C++的思維方式解決問(wèn)題,對(duì)于對(duì)C語(yǔ)言已經(jīng)很熟悉的人來(lái)說(shuō)會(huì)很不能適應(yīng)。需要一段時(shí)間來(lái)適應(yīng),不然會(huì)將代碼寫(xiě)的似是而非。而且不能邯鄲學(xué)步,必須從思想上徹底的C++(OO),如果只是依葫蘆畫(huà)瓢,那結(jié)果很可能是用C++的語(yǔ)法編寫(xiě)C式的程序。本人曾經(jīng)犯的典型的低級(jí)的錯(cuò)誤之一,就是無(wú)意識(shí)的一個(gè)類(lèi)無(wú)限制的擴(kuò)充,完全沒(méi)有考慮到類(lèi)的多層結(jié)構(gòu)(基類(lèi)-派生類(lèi)),需要屬性或方法便在類(lèi)中增加,雖然也用到了多態(tài)、重載等一些OO的設(shè)計(jì)方式,但最后這個(gè)類(lèi)龐大無(wú)比,除了在當(dāng)前系統(tǒng)中任勞任怨的工作外,一點(diǎn)復(fù)用的可能都沒(méi)有,如果另一個(gè)系統(tǒng)還需要一個(gè)類(lèi)似的東西,那只能重新設(shè)計(jì)實(shí)現(xiàn)一個(gè)新的類(lèi)。并且最致命的是在維護(hù)更新時(shí)帶來(lái)得麻煩,需要不斷全部編譯不說(shuō),而且代碼在用了大量注釋后,在過(guò)一段時(shí)間讀起來(lái)也是一件重腦力勞動(dòng)。及失去了C的簡(jiǎn)潔清晰和高效,也不完全具備C++的面向?qū)ο蟮奶匦?。這根本不能叫C++程序。(我想有時(shí)間重寫(xiě)一下以前代碼也會(huì)有很多收獲,溫故而知新嗎)C和C++在編程思想上是相互矛盾的。這也就是說(shuō)如果你想學(xué)C++,完全可以不學(xué)C,只需要一本好書(shū)和一個(gè)不太笨的大腦再加上努力就可以了,如果你已有C的經(jīng)驗(yàn)在一定的情況下反而會(huì)搗亂。
     本章是對(duì)對(duì)象模型的一個(gè)大略瀏覽。既然我們選擇了C++而不是C作為開(kāi)發(fā)工具,那我們的編程思想也應(yīng)該轉(zhuǎn)為C++的,而不能再延續(xù)C的Procedural方式。我們必須學(xué)會(huì)C++的思考方式。采用抽象數(shù)據(jù)類(lèi)型或用一個(gè)多層的class體系對(duì)數(shù)據(jù)以及數(shù)據(jù)處理函數(shù)進(jìn)行封裝,只有擺脫C程序的使用全局?jǐn)?shù)據(jù)的慣性,才能充分發(fā)揮出C++對(duì)象模型的強(qiáng)大威力。
     在C++中有兩種數(shù)據(jù)成員static和nonstatic,以及三種成員函數(shù)static、nonstatic和virtual。C++對(duì)象模型對(duì)內(nèi)存空間和存取時(shí)間做了優(yōu)化,nonstatic的數(shù)據(jù)成員被置于類(lèi)對(duì)象之內(nèi),而static數(shù)據(jù)成員被置于類(lèi)對(duì)象之外。static和nonstatic成員函數(shù)被放在類(lèi)對(duì)象之外。而virtual函數(shù)是由類(lèi)對(duì)象的一個(gè)指向vtbl(虛函數(shù)表)的指針vptr來(lái)進(jìn)行支持。而vptr的設(shè)定和重置由類(lèi)的構(gòu)造函數(shù)、析構(gòu)函數(shù)以及copy assignment運(yùn)算符自動(dòng)完成。
     我們?cè)O(shè)計(jì)的每一個(gè)類(lèi)幾乎都要有一個(gè)或多個(gè)構(gòu)造函數(shù)、析構(gòu)函數(shù)和一個(gè)Assignment運(yùn)算符。他們的作用是構(gòu)造函數(shù)產(chǎn)生一個(gè)新的對(duì)象并確定它被初始化。析構(gòu)函數(shù)銷(xiāo)毀一個(gè)對(duì)象并確定它已經(jīng)被適當(dāng)?shù)那謇恚ū苊獬霈F(xiàn)內(nèi)存泄露的問(wèn)題),Assignment運(yùn)算符給對(duì)象一個(gè)新值。
     這是第一章的第一部分,由于雷神最近幾天在做模式小組的主頁(yè),時(shí)間周轉(zhuǎn)不開(kāi)了。本想寫(xiě)完整個(gè)一章再發(fā),考慮一下還是先發(fā)一部分吧。原因有2。1、第一章的后半部可能又要拖上10天半個(gè)月的。2、筆記實(shí)在難寫(xiě),我不愿意將筆記做成將書(shū)上的重點(diǎn)再抄一邊,而是喜歡盡量將自己的理解描述出來(lái),誰(shuí)知第一章便如此的難以消化,已經(jīng)反復(fù)讀了3遍,還是有些夾生。所以本著對(duì)大家和自己負(fù)責(zé)的態(tài)度,雷神準(zhǔn)備再看它3遍在說(shuō)。突然發(fā)現(xiàn)自己的C++還差的很遠(yuǎn),好可怕呀。