版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第五章繼承與派生2023/4/232派生類(lèi)的引入C++的類(lèi)提供了良好的模塊分解技術(shù),也具有可重用軟件所期望的品質(zhì):它們是相似一致的模塊,通過(guò)信息隱藏,將它們的接口和實(shí)現(xiàn)清楚地分開(kāi)來(lái)。我們還希望在類(lèi)的基礎(chǔ)上能取得更好的可重用性和可擴(kuò)充性的目標(biāo)。面向?qū)ο蟮睦^承技術(shù)提供了實(shí)現(xiàn)上述目標(biāo)的有力手段。2023/4/233現(xiàn)實(shí)中的繼承與派生在自然界中,繼承這個(gè)概念是非常普遍的。例如:小貓仔繼承了貓爸貓媽的特性,所以長(zhǎng)的是貓鼻子貓眼,我們不會(huì)把它錯(cuò)認(rèn)為是小狗。繼承就是將一些本質(zhì)的特性遺傳給子代,使后代在很大程度上具有與父代相同的性質(zhì)。子代同時(shí)還具有父代沒(méi)有的特性。2023/4/234再來(lái)看一個(gè)現(xiàn)實(shí)世界中的例子:RectangleSquareDiamondParallelogramQuadrangle四邊形是一個(gè)基本的概念,矩形、正方形、菱形和平行四邊形都是派生的概念,因?yàn)樗鼈兌紝儆谒倪呅?,它們繼承了四邊形的所有性質(zhì),同時(shí)又?jǐn)U充出各自的特性。2023/4/235不具有對(duì)稱性不是所有植物都屬于蕨類(lèi)傳遞性
高等植物、蕨類(lèi)植物、芒萁都是植物,具有植物的共同特征植物
低等植物高等植物藻類(lèi)菌類(lèi)地衣類(lèi)苔蘚類(lèi)蕨類(lèi)裸子類(lèi)被子類(lèi)地錢(qián)小金發(fā)草毛蕨芒萁杉木柏木荔枝橘子再來(lái)看一個(gè)現(xiàn)實(shí)世界中的例子:2023/4/236從上面的例子可以看出:而且子代可以擁有父代沒(méi)有的特性,這是可擴(kuò)充的概念。一旦指定了某種事物父代的本質(zhì)特征,那么它的子代將會(huì)自動(dòng)具有那些性質(zhì)。這就是一種樸素的可重用的概念。2023/4/237從軟件設(shè)計(jì)的角度來(lái)看:基于已有的類(lèi),可以建立新的類(lèi)。這個(gè)新的類(lèi)既重用已有類(lèi)的功能,又?jǐn)U展了新的功能。類(lèi)是某類(lèi)事物共同特性的體現(xiàn),它對(duì)外提供了特定的功能。2023/4/238C++的繼承關(guān)系繼承就是在一個(gè)已經(jīng)存在的類(lèi)的基礎(chǔ)上建立另一個(gè)新的類(lèi)?;?lèi)派生類(lèi)已存在的類(lèi)稱為“基類(lèi)”或“父類(lèi)”,新建立的類(lèi)稱為“派生類(lèi)”或“子類(lèi)”,如圖所示:2023/4/239派生類(lèi)的功能主要通過(guò)以下方式來(lái)體現(xiàn):派生類(lèi)的特性吸收基類(lèi)成員添加新成員改造基類(lèi)成員從編碼的角度來(lái)看,派生類(lèi)從基類(lèi)中以較低的代價(jià)換來(lái)了較大的靈活性。一旦產(chǎn)生了可靠的基類(lèi),只需要調(diào)試派生類(lèi)中所作的修改即可。派生類(lèi)可以對(duì)繼承的屬性進(jìn)行擴(kuò)展、限制或改變。2023/4/2310單繼承和多繼承單繼承:派生類(lèi)只有一個(gè)直接基類(lèi)ABC單繼承XYZ多繼承多繼承:派生類(lèi)有多個(gè)直接基類(lèi)2023/4/2311單繼承派生類(lèi)定義單繼承派生類(lèi)的語(yǔ)法格式:
class派生類(lèi)名:<繼承方式>基類(lèi)名{ ……//派生類(lèi)新添加的成員 };“繼承方式”可以是public、private、以及protected。雖然繼承了基類(lèi)的所有成員,但是派生類(lèi)并非都能訪問(wèn)基類(lèi)的所有成員,繼承方式會(huì)影響派生類(lèi)對(duì)基類(lèi)中各種成員的引用。2023/4/2312公有派生類(lèi)在聲明派生類(lèi)時(shí)將繼承方式指定為public時(shí),該類(lèi)稱為公有派生類(lèi)。class派生類(lèi)名:public基類(lèi)名
{ ……//派生類(lèi)新添加的成員};2023/4/23137.2.1訪問(wèn)控制public成員protected成員private成員public成員protected成員private成員基類(lèi)派生類(lèi)2023/4/2314基類(lèi)的成員在公有派生類(lèi)中的引用權(quán)限基類(lèi)公有成員私有成員保護(hù)成員公有派生類(lèi)公有成員不可訪問(wèn)成員保護(hù)成員不可訪問(wèn)成員在類(lèi)外不能被直接訪問(wèn)。在派生類(lèi)的類(lèi)內(nèi)不能被直接訪問(wèn)。2023/4/2315舉例:公有派生classBase{ intv1;public: intv2; Base(inta=0,intb=0){ v1=a;v2=b; }};classDerived:publicBase{ intv3;public: intv4; Derived(inta=0,intb=0){ v3=a;v4=b; } voidfunc(){ intsum1=v1+v2+v3+v4; intsum2=v2+v3+v4; }};voidmain(){ Derivedobj(5,6); obj.v2=8;}//錯(cuò)誤2023/4/2316私有派生類(lèi)在聲明派生類(lèi)時(shí)將繼承方式指定為private時(shí),該類(lèi)稱為私有派生類(lèi)。class派生類(lèi)名:private基類(lèi)名{……//派生類(lèi)新添加的成員};2023/4/2317基類(lèi)的成員在私有派生類(lèi)中的引用權(quán)限基類(lèi)公有成員私有成員保護(hù)成員私有派生類(lèi)私有成員不可訪問(wèn)成員私有成員2023/4/2318舉例:私有派生classBase{ intv1;public: intv2; Base(inta=0,intb=0){ v1=a;v2=b; }};classDerived:privateBase{ intv3;public: intv4; Derived(inta=0,intb=0){ v3=a;v4=b; } voidfunc(){ intsum1=v1+v2+v3+v4; intsum2=v2+v3+v4; }};voidmain(){ Derivedobj(5,6); obj.v2=8;//錯(cuò)誤//錯(cuò)誤2023/4/2319公有派生和私有派生的比較雖然派生類(lèi)繼承了基類(lèi)所有的成員,但是基類(lèi)的私有成員對(duì)于派生類(lèi)來(lái)說(shuō)是不可見(jiàn)的,因此不能被派生類(lèi)所訪問(wèn)。基類(lèi)公有成員私有成員保護(hù)成員公有派生類(lèi)公有成員不可訪問(wèn)成員保護(hù)成員私有派生類(lèi)私有成員不可訪問(wèn)成員私有成員2023/4/2320保護(hù)成員的引入為了解決這個(gè)問(wèn)題,C++專門(mén)設(shè)置了保護(hù)成員,即用protected關(guān)鍵字說(shuō)明的成員。保護(hù)成員的特性:能夠被基類(lèi)和派生類(lèi)所訪問(wèn)。和私有成員一樣,類(lèi)外不能訪問(wèn)。2023/4/2321舉例:保護(hù)成員classBase{protected: intv1;public: intv2; Base(inta=0,intb=0){ v1=a;v2=b; }};classDerived:publicBase{ intv3;public: intv4; Derived(inta=0,intb=0){ v3=a;v4=b; } voidfunc(){ intsum1=v1+v2+v3+v4; intsum2=v2+v3+v4; }};voidmain(){ Derivedobj(5,6); obj.v1=8;}//錯(cuò)誤//正確2023/4/2322保護(hù)派生類(lèi)在聲明派生類(lèi)時(shí)將繼承方式指定為protected時(shí),該類(lèi)稱為保護(hù)派生類(lèi):class派生類(lèi)名:protected基類(lèi)名
{……//派生類(lèi)新添加的成員};2023/4/2323基類(lèi)的成員在保護(hù)派生類(lèi)中的引用權(quán)限基類(lèi)公有成員私有成員保護(hù)成員保護(hù)派生類(lèi)保護(hù)成員不可訪問(wèn)成員保護(hù)成員2023/4/2324小結(jié)不同的繼承方式,子類(lèi)對(duì)基類(lèi)中的成員的訪問(wèn)權(quán)限如下表所示:基類(lèi)公有成員私有成員保護(hù)成員公有派生類(lèi)公有成員不可訪問(wèn)成員保護(hù)成員保護(hù)派生類(lèi)保護(hù)成員不可訪問(wèn)成員保護(hù)成員私有派生類(lèi)私有成員不可訪問(wèn)成員私有成員2023/4/2325派生類(lèi)與基類(lèi)同名成員的訪問(wèn)方式C++允許派生類(lèi)可以重新定義基類(lèi)的成員,此時(shí)稱派生類(lèi)的成員覆蓋了基類(lèi)的同名成員。如果在派生類(lèi)中,想使用基類(lèi)的同名成員,則可以顯式地使用類(lèi)名+限定符的方式,如下所示:基類(lèi)名::成員2023/4/2326舉例classBase{protected: intv1;public: intv2; Base(inta=0,intb=0){ v1=a;v2=b; }};classDerived:publicBase{ intv2;public: intv3; Derived(inta=0,intb=0){ v2=a;v3=b; } voidfunc(){
intsum1=v1+v2+v3;
intsum2=v1+Base::v2+v3; }};voidmain(){ Derivedobj(5,6); obj.v2=8;}//錯(cuò)誤 obj.Base::v2=9;//使用的是Derived中的v2//使用的是Base中的v22023/4/2327派生類(lèi)對(duì)象的構(gòu)造和析構(gòu)派生類(lèi)對(duì)象數(shù)據(jù)成員的構(gòu)成:從基類(lèi)繼承過(guò)來(lái)的數(shù)據(jù)成員派生類(lèi)自定義的數(shù)據(jù)成員如何初始化這幾部分?jǐn)?shù)據(jù)成員呢?基本數(shù)據(jù)類(lèi)型類(lèi)類(lèi)型如何析構(gòu)派生類(lèi)對(duì)象?2023/4/2328單繼承派生類(lèi)的構(gòu)造函數(shù)派生類(lèi)構(gòu)造函數(shù)(參數(shù)表):基類(lèi)構(gòu)造函數(shù)(參數(shù)表),對(duì)象成員1(參數(shù)表),
…… 對(duì)象成員n(參數(shù)表),{
……//初始化自定義數(shù)據(jù)成員}如果基類(lèi)使用的是缺省的構(gòu)造函數(shù)或不帶參數(shù)的構(gòu)造函數(shù),那么在初始化列表中可以省略“基類(lèi)構(gòu)造函數(shù)(參數(shù)表)“這一項(xiàng)。如果沒(méi)有對(duì)象成員,那么在初始化列表中可以省略“對(duì)象成員(參數(shù)表)“這一項(xiàng)。2023/4/2329構(gòu)造函數(shù)的調(diào)用順序如下:構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用順序先調(diào)用基類(lèi)構(gòu)造函數(shù);再調(diào)用對(duì)象成員所屬類(lèi)的構(gòu)造函數(shù);最后調(diào)用派生類(lèi)構(gòu)造函數(shù);析構(gòu)函數(shù)的調(diào)用順序如下:再調(diào)用對(duì)象成員所屬類(lèi)的析構(gòu)函數(shù);先調(diào)用派生類(lèi)的析構(gòu)函數(shù);最后調(diào)用基類(lèi)的析構(gòu)函數(shù);2023/4/2330舉例classBase{public:Base(){cout<<“Basecreated\n”;}};classDerived:publicBase{public:Derived(){cout<<“Derivedcreated\n”;}};voidmain(){ Derivedd;}2023/4/2331請(qǐng)分析classbase{ intx;public: base(inti):x(i){ cout<<"base\n"; }};classderived:publicbase{ inta;public: derived(inti):a(i*4),base(a){ cout<<"derived\n"; }};此時(shí)基類(lèi)的數(shù)據(jù)成員x的值為多少?2023/4/2332賦值兼容規(guī)則在公有派生方式下,派生類(lèi)對(duì)象可以作為基類(lèi)對(duì)象來(lái)使用,具體方式如下:以上規(guī)則的具體使用方式:派生類(lèi)的對(duì)象可以直接賦值給基類(lèi)的對(duì)象基類(lèi)對(duì)象的引用可以引用一個(gè)派生類(lèi)對(duì)象基類(lèi)對(duì)象的指針可以指向一個(gè)派生類(lèi)對(duì)象BaseBobj;DerivedDobj;Bobj=Dobj;Base&refB=Dobj;Base*pB=&Dobj;2023/4/2333需要思考的兩個(gè)問(wèn)題為什么是“派生類(lèi)對(duì)象->基類(lèi)對(duì)象”,而不是“基類(lèi)對(duì)象->派生類(lèi)對(duì)象”?其他繼承方式會(huì)有以上規(guī)則嗎?2023/4/2334解決第一個(gè)問(wèn)題v1v2v1v2v3v4基類(lèi)對(duì)象派生類(lèi)對(duì)象基類(lèi)對(duì)象和派生類(lèi)對(duì)象的內(nèi)存布局方式當(dāng)一個(gè)派生類(lèi)對(duì)象直接賦值給基類(lèi)對(duì)象時(shí),不是所有的數(shù)據(jù)都賦給了基類(lèi)對(duì)象,賦予的只是派生類(lèi)對(duì)象的一部分。這部分叫做派生類(lèi)對(duì)象的“切片”(sliced)。2023/4/2335解決第二個(gè)問(wèn)題回憶一下不同的繼承方式,子類(lèi)對(duì)基類(lèi)中的成員的訪問(wèn)權(quán)限:基類(lèi)公有成員私有成員保護(hù)成員公有派生類(lèi)公有成員不可訪問(wèn)成員保護(hù)成員私有派生類(lèi)私有成員不可訪問(wèn)成員私有成員保護(hù)派生類(lèi)保護(hù)成員不可訪問(wèn)成員保護(hù)成員只有在公有派生的情況下,才有可能出現(xiàn)“基類(lèi)的公有成員變成派生類(lèi)的公有成員”的情況。2023/4/2336多繼承派生類(lèi)派生類(lèi)有多個(gè)直接基類(lèi),這叫多繼承。QuadrangleDiamondSquareRectangleQuadrangle2023/4/2337定義多繼承派生類(lèi)的語(yǔ)法格式:class派生類(lèi)名:<繼承方式1>基類(lèi)名1, <繼承方式2>基類(lèi)名2,
……{
……//派生類(lèi)新添加的成員};2023/4/2338多繼承派生類(lèi)對(duì)象的構(gòu)造和析構(gòu)多繼承派生類(lèi)的構(gòu)造函數(shù):派生類(lèi)名(參數(shù)表):基類(lèi)名1(參數(shù)表1),
基類(lèi)名2(參數(shù)表2),
對(duì)象成員1(參數(shù)表3), 對(duì)象成員2(參數(shù)表4),
…{ //派生類(lèi)新添加的成員}2023/4/2339派生類(lèi)構(gòu)造函數(shù)的執(zhí)行順序:先執(zhí)行所有基類(lèi)的構(gòu)造函數(shù)(按這些基類(lèi)被繼承時(shí)聲明順序依次執(zhí)行基類(lèi)1、基類(lèi)2的構(gòu)造函數(shù))。最后執(zhí)行派生類(lèi)本身的構(gòu)造函數(shù)。再執(zhí)行對(duì)象成員所屬類(lèi)的構(gòu)造函數(shù)(按照這些對(duì)象成員在類(lèi)中定義的順序)。2023/4/2340多繼承中的二義性問(wèn)題在多繼承中,一個(gè)類(lèi)不可以重復(fù)成為另一個(gè)類(lèi)的直接基類(lèi),但可以多次成為間接基類(lèi)。此時(shí)派生類(lèi)訪問(wèn)基類(lèi)成員時(shí)可能出現(xiàn)二義性。訪問(wèn)共同基類(lèi)的成員時(shí)可能出現(xiàn)二義性。訪問(wèn)不同基類(lèi)的具有相同名字成員時(shí)可能出現(xiàn)二義性。2023/4/2341訪問(wèn)不同基類(lèi)同名成員時(shí)的二義性
classA{public:
intvalue;voidf();};classB{public:intvalue;voidf();voidg();};classC:publicA,publicB{public:voidg();voidh();};voidmain(){CC1;
C1.f();
C1.value=9;}//出現(xiàn)二義性//出現(xiàn)二義性解決辦法是用類(lèi)名對(duì)成員加以限定,例如:
C1.A::f();或者C1.B::f(); C1.A::value=9;或者C1.B::value=9;2023/4/2342訪問(wèn)共同基類(lèi)成員時(shí)的二義性
classA{ public: inta; voidg();};classB1:publicA{ intb1;};classB2:publicA{ intb2;};classC:publicB1,publicB2{ intc;public:intf();};voidmain(){CCobj;Cobj.a=8;Cobj.A::a=9;
Cobj.g();}//出現(xiàn)二義性//出現(xiàn)二義性//出現(xiàn)二義性解決辦法:Cobj.B1::a=9;或Cobj.B2::a=9;2023/4/2343以上類(lèi)的關(guān)系如下圖所示:A(a,g())B1(b1)A(a,g())B2(b2)C(f(),c)類(lèi)A是派生類(lèi)C兩條繼承路徑上的一個(gè)公共基類(lèi),因此這個(gè)公共基類(lèi)會(huì)在派生類(lèi)對(duì)象中產(chǎn)生兩個(gè)基類(lèi)子對(duì)象。雖然可以通過(guò)類(lèi)限定符的方式避免二義性,但問(wèn)題的關(guān)鍵在于我們不需要在派生類(lèi)對(duì)象中存在多個(gè)基類(lèi)對(duì)象的拷貝!如果要使這個(gè)公共基類(lèi)在派生類(lèi)中只產(chǎn)生一個(gè)基類(lèi)子對(duì)象,則需要將這個(gè)基類(lèi)設(shè)置為虛基類(lèi)。2023/4/2344虛基類(lèi)引進(jìn)虛基類(lèi)的目的是為了解決二義性問(wèn)題,使公共基類(lèi)在其派生類(lèi)對(duì)象中只產(chǎn)生一個(gè)基類(lèi)子對(duì)象。虛基類(lèi)說(shuō)明格式如下:
virtual<繼承方式><基類(lèi)名>在“繼承方式”前面用關(guān)鍵字virtual來(lái)說(shuō)明2023/4/2345例子:虛基類(lèi)的使用
classA{ public: inta; voidg();};classB1:virturalpublicA{ intb1;};classB2:virturalpublicA{ intb2;};classC:publicB1,publicB2{ intc;public:intf();};voidmain(){CCobj;Cobj.a=8;//或Cobj.A::a=9;Cobj.g();}2023/4/2346A(g(),a)B1(b1)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 學(xué)生實(shí)習(xí)期間家長(zhǎng)保證書(shū)
- 版汽運(yùn)運(yùn)輸合同
- 生鮮食品采購(gòu)合同
- 煤炭購(gòu)銷(xiāo)合同范本模板
- 政府采購(gòu)合同履行
- 招標(biāo)談判文件的編輯技巧
- 商場(chǎng)店鋪接盤(pán)合同模板
- 房屋買(mǎi)賣(mài)合同補(bǔ)充協(xié)議范例
- 簡(jiǎn)單易懂的投資理財(cái)合同
- 業(yè)績(jī)分享合同樣本
- 湖南涉外經(jīng)濟(jì)學(xué)院論文答辯高校通用ppt模版
- 南極磷蝦油100問(wèn)專業(yè)版
- 機(jī)械課程設(shè)計(jì)說(shuō)明書(shū)
- 北師大2019新版高中英語(yǔ)選擇性必修二UNIT 6 THE MEDIA單詞表
- 冰蓄冷系統(tǒng)技術(shù)方案及經(jīng)濟(jì)性分析
- 歌曲簡(jiǎn)譜國(guó)家成龍
- 設(shè)備安裝工程監(jiān)理規(guī)劃
- 防止機(jī)組非計(jì)劃停運(yùn)措施(鍋爐專業(yè))
- 素材的獲取與處理方法
- 如何同步同時(shí)接收老公老婆微信的實(shí)用教程
- 場(chǎng)調(diào)查報(bào)告封面
評(píng)論
0/150
提交評(píng)論