?? 深度探索c++對(duì)象模型(4).txt
字號(hào):
雷神跌跌撞撞的讀完了《深度探索C++對(duì)象模型》的第一章,雖然還是有些疑惑,但是已經(jīng)感到收獲很大。按照朋友的說法,第一章是一個(gè)概括的介紹,具體的細(xì)節(jié)會(huì)在以后的章節(jié)闡述,如果沒有通讀本書,第一章還是比較不容易理解的。雷神聽過之后信心倍增,也不在有初看此書時(shí)的“世界末日”的感覺了(在第2篇雷神感到學(xué)了近一年的C++,居然水平如此之差),并且通過自己的努力,還是摸到了些門道,所以讓我們繼續(xù)快樂的出發(fā),踏上深度探索C++對(duì)象模型的旅程。記住我們?cè)诘谝黄男∥摹秷?jiān)持不懈,直到成功》,這可是獲得成功的不二法門。
第二章主要講的的構(gòu)造函數(shù)語(yǔ)意(Semantics),這是一個(gè)什么意思?我的英文和中文學(xué)的都不好,但我想是書上弄錯(cuò)了(也許只是一個(gè)筆誤),也許應(yīng)該翻譯成語(yǔ)義比較恰當(dāng)。The study or science of meaning in anguage forms. 語(yǔ)義學(xué)以語(yǔ)言形式表示意思的研究或科學(xué)。我們要研究構(gòu)造函數(shù)的,并且以語(yǔ)言的形式將它描述清楚。
看完題目我的第一個(gè)感覺,構(gòu)造函數(shù)我知道。構(gòu)造函數(shù)是一個(gè)類的成員函數(shù),構(gòu)造函數(shù)和析構(gòu)函數(shù)是進(jìn)行對(duì)象數(shù)據(jù)的創(chuàng)建,初始化,清除工作的成員函數(shù),可以重載構(gòu)造函數(shù),使一個(gè)類不止具備一個(gè)構(gòu)造函數(shù),因有時(shí)需要以這些方法中的某一種分別創(chuàng)建不同的對(duì)象。不能重載析構(gòu)函數(shù)。構(gòu)造函數(shù)作為成員函數(shù)和類有相同的名字。例:一個(gè)類名為:aClass,構(gòu)造函數(shù)就是aClass()。構(gòu)造函數(shù)沒有返回值,而且不能定義其返回類型,void也不行。析構(gòu)函數(shù)同樣使用這一點(diǎn)。當(dāng)編寫重載函數(shù)時(shí),只有參數(shù)表不同,通過比較其參數(shù)個(gè)數(shù)或參數(shù)類型可以區(qū)分兩個(gè)重載函數(shù)。但是我讀完第一小段后就知道這一章要告訴我們什么了。
這一章并不是要告訴我們什么是構(gòu)造函數(shù),它的作用是什么。而是要告訴我們的是構(gòu)造函數(shù)是如何工作的。我的。在得知這點(diǎn)后我很興奮,因?yàn)槲掖_實(shí)不知道構(gòu)造函數(shù)是如何構(gòu)造一個(gè)類的對(duì)象的,并且一直想知道。我一直對(duì)面向?qū)ο笊衿娴墓δ芎芨信d趣。為什么一個(gè)類在被實(shí)例化時(shí),可以自動(dòng)的完成很多工作,使我們的主函數(shù)清晰,簡(jiǎn)單,穩(wěn)健,高效。以前只看到了表面,沒有深入,這會(huì)我們有機(jī)會(huì)去皮剔肉深入骨髓了。 書上主要討論了幾種情況:
帶有缺省構(gòu)造函數(shù)的成員對(duì)象。如果一個(gè)類沒有任何的構(gòu)造函數(shù),但他有一個(gè)成員對(duì)象,這個(gè)對(duì)象的類有一個(gè)缺省的構(gòu)造函數(shù),那么編譯器會(huì)在需要的時(shí)候?yàn)檫@個(gè)類合成一個(gè)構(gòu)造函數(shù)。
舉個(gè)例子:
我們有以下幾個(gè)類。它們都有一個(gè)構(gòu)造函數(shù)。
貓{public:貓(),......};
狗{public:狗(),......};
鳥{public:鳥(),......};
魚{public:魚(),......};
我們又有一個(gè)類。寵物,我們將貓作為它的成員之一。并且沒有給它聲明構(gòu)造函數(shù)。
寵物{
public:
貓 一只貓;
狗 一只狗;
鳥 一只鳥;
魚 一只魚;
private:
int ival;
......
}
則當(dāng)需要的時(shí)候編譯器會(huì)為它合成一個(gè)構(gòu)造函數(shù),并且采用內(nèi)聯(lián)方式。大概象下面的樣子。
inline
寵物::寵物()
{
貓.貓::貓();
狗.狗::狗();
鳥.鳥::鳥();
魚.魚::魚();
ival=0;
}
為什么會(huì)這樣,我們來(lái)看看編譯器的行動(dòng)。編譯器開始執(zhí)行用戶的代碼,準(zhǔn)備生成寵物對(duì)象之前,會(huì)首先調(diào)用必要的構(gòu)造函數(shù),來(lái)初始化類的成員,以便為對(duì)象分配合適的內(nèi)存空間。結(jié)果編譯器會(huì)合成上面的構(gòu)造函數(shù),如果程序員為寵物類寫了一個(gè)構(gòu)造函數(shù)。 寵物::寵物(){ival=0;}那編譯器也會(huì)將這個(gè)構(gòu)造函數(shù)擴(kuò)張成上面的那樣。編譯器是怎樣實(shí)現(xiàn)的呢?原來(lái)當(dāng)一個(gè)類沒有任何用戶定義的構(gòu)造函數(shù),而是由編譯器自動(dòng)生成的話,則這個(gè)被暗中生成的構(gòu)造函數(shù)將會(huì)是一個(gè)沒有什么用處的構(gòu)造函數(shù)。但是通過編譯器的工作能夠?yàn)槲覀兒铣梢粋€(gè)nontrivial default constructor.
好象香港電影中演的,如果你惹上官司(你要設(shè)計(jì)一個(gè)類),你又沒有錢去請(qǐng)高級(jí)的律師(沒有給出構(gòu)造函數(shù)),那會(huì)給你分配一個(gè)律師(缺省的構(gòu)造函數(shù)),當(dāng)然這個(gè)律師的能力也許和那些大律師比起來(lái)有差距(trivial)。不過我們要知道他們也不是一點(diǎn)用都沒有。但是由于有律師行的督導(dǎo),可以使這些律師能夠努力做到最好(nontrivial)。
同樣的道理,我們可以理解另外的幾種nontrivial default constructor的情況。
如果你的類沒有任何的構(gòu)造函數(shù),并且它派生于一個(gè)有著缺省構(gòu)造函數(shù)的基類,那這個(gè)派生類的缺省構(gòu)造函數(shù)會(huì)被視為nontrivial,因此需要被合成出來(lái),他的合成步驟是調(diào)用上一層基類的缺省構(gòu)造函數(shù),并根據(jù)它們的聲明次序?yàn)榕缮惡铣梢粋€(gè)構(gòu)造函數(shù)。
如果類聲明或繼承了一個(gè)虛函數(shù),或者類派生于一個(gè)繼承串鏈,其中有一個(gè)或更多的虛擬基類。由于缺少使用者聲明的構(gòu)造函數(shù),則編譯器會(huì)合成一個(gè)缺省的構(gòu)造函數(shù),以便正確的初始化每一個(gè)類對(duì)象的vptr。
最后說一點(diǎn),在合成的缺省構(gòu)造函數(shù)中,只有基類的子對(duì)象和類的成員對(duì)象會(huì)被初始化,所有其他的非靜態(tài)數(shù)據(jù)成員都不會(huì)被初始化,因?yàn)檫@些操作是需要程序員來(lái)做的。編譯器沒有必要連這些工作都做了。 好了,這篇就寫到這里吧。這本書真的是雷神所看過的書中,看的最慢的一本了。但這些深層的知識(shí)有必要了解的很清楚嗎,我們不知道編譯器如何合成缺省的構(gòu)造函數(shù)不也能寫程序嗎?雷神用侯大師的話來(lái)回答這個(gè)問題:練從難處練,用從易處用。知其然而不知其所以然,不是一個(gè)嚴(yán)謹(jǐn)?shù)膶W(xué)習(xí)態(tài)度。
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -