在完成了C++面向?qū)ο蟾呒?jí)編程(上)第三周的學(xué)習(xí)之后,有一些總結(jié)和心得在這里通過(guò)學(xué)習(xí)筆記的方式分享出來(lái),供也在學(xué)習(xí)C++的小伙伴用作學(xué)習(xí)交流,如有理解不到位的地方,歡迎批評(píng)指正。
本周學(xué)習(xí)了Object?Oriented Programming(OOP),Object Oriented Design(OOD),其實(shí)也就是類與類之間的關(guān)系。類與類之間有以下三種關(guān)系:
Composition(復(fù)合)
Delegation(委托)
Inheritance(繼承)
一.Composition(復(fù)合)
復(fù)合表示一種包含關(guān)系,即has-a,可以用下圖形象的表示:

Container容納了component,即擁有component中的功能,復(fù)合關(guān)系下的構(gòu)造由內(nèi)而外,析構(gòu)則由外內(nèi),當(dāng)然,這是由編譯器去自動(dòng)完成的,并且,兩個(gè)類的生命周期是一致的。
二.Delegation(委托)
我覺(jué)得復(fù)合和委托的區(qū)別就在于前者包含的是類本身,而后者則包含的是類的指針,所以委托其實(shí)也是一種復(fù)合,是component by reference,可以用下圖表示:

當(dāng)String需要的時(shí)候就會(huì)通過(guò)指針調(diào)用StringRep中的函數(shù)。但與復(fù)合不同的是,String對(duì)象會(huì)先被創(chuàng)建,等需要的時(shí)候再創(chuàng)建StringRep對(duì)象。功能的設(shè)計(jì)體現(xiàn)在StringRep中,而String只是實(shí)現(xiàn)了一個(gè)接口,那么,當(dāng)我們需要改動(dòng)的時(shí)候,只需要改動(dòng)StringRep,不需要?jiǎng)覵tring,這樣就形成了編譯防火墻,這也就是Handle/Body(pImpl)的設(shè)計(jì)模式。這樣,a、b、c不同的接口都可以指向同一個(gè)object,大大節(jié)省了內(nèi)存。

三.Inheritance(繼承)
繼承是一種父與子的關(guān)系,即is-a。子類對(duì)象可以使用父類對(duì)象中的數(shù)據(jù)調(diào)用父類對(duì)象的函數(shù),如下圖所示:

構(gòu)造和析構(gòu)的原理也跟復(fù)合關(guān)系一樣,構(gòu)造由內(nèi)而外,析構(gòu)由外而內(nèi)。

繼承通常是搭配virtual function(虛函數(shù))來(lái)使用,在語(yǔ)法上只要在成員函數(shù)之前加上virtual就是虛函數(shù)了。下面例子中的pure virtual是不會(huì)在父類中定義的,要求子類必須重新定義,即復(fù)寫(override,這是一個(gè)專有名詞,只能在虛函數(shù)被重新定義時(shí)使用);impure virtual是在父類中有默認(rèn)定義,子類中可以override;non-virtual在父類中已經(jīng)定義了,并且不希望子類去override。

四.三種關(guān)系的組合
1.Inheritance(繼承)+ composition(復(fù)合)

對(duì)于第二種關(guān)系的構(gòu)造和析構(gòu),按照內(nèi)外的原則,很明顯構(gòu)造是先component,再父類,最后子類,析構(gòu)則相反,由外而內(nèi),這很好理解;至于第一種,我認(rèn)為父類和子類中的包含部分其實(shí)可以看成是并列關(guān)系,編譯器如何去安排構(gòu)造和析構(gòu)的順序,對(duì)程序本身沒(méi)有什么影響。
2.Delegation(委托)+ inheritance(繼承)

老師舉了一個(gè)多窗口查看文件的例子。文件或者數(shù)據(jù)跟各個(gè)窗口之間是委托的關(guān)系,窗口可以寫成虛函數(shù),讓子函數(shù)去復(fù)寫具體窗口的內(nèi)容如何實(shí)現(xiàn)。
?ZZZ??????