




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、C+面向?qū)ο蟪绦蛟O(shè)計(jì)普通高等教育“十一五”國家級規(guī)劃教材中國高等院校計(jì)算機(jī)基礎(chǔ)教育課程體系規(guī)劃教材 1第11講 繼承與派生 11.1 授課內(nèi)容授課內(nèi)容繼承與派生的應(yīng)用繼承與派生的應(yīng)用。主要內(nèi)容:。主要內(nèi)容:1多重繼承;多重繼承;2虛基類;虛基類;3繼承與派生的應(yīng)用。繼承與派生的應(yīng)用。2第11講 繼承與派生11.2 授課要求授課要求(1)理解多重繼承的含義、定義方法和實(shí)現(xiàn);)理解多重繼承的含義、定義方法和實(shí)現(xiàn);(2)理解虛基類及其作用。)理解虛基類及其作用。3第11講 繼承與派生 11.3 授課重點(diǎn)授課重點(diǎn)1重點(diǎn)是多重繼承和派生類的應(yīng)用。11.4 授課難點(diǎn)授課難點(diǎn)1難點(diǎn)是派生類的應(yīng)用。41多重繼
2、承多重繼承前面討論了單繼承,即一個類是從一個基類派生而來的。實(shí)際上,常常有這樣的情況: 一個派生類有兩個或多個基類一個派生類有兩個或多個基類,派生類從兩個或多個基類中繼承所需的屬性。多重繼承多重繼承:允許一個派生類同時繼承多個基類。這種行為稱為多重繼承(multiple inheritance)。5(1)聲明多重繼承的方法方法:在單繼承的基礎(chǔ)上,依次列出多個基類。比如:如果已聲明了類A、類B和類C,可以聲明多重繼承的派生類D:class D:public A, private B, protected C類類D新增加的成員新增加的成員D按不同的繼承方式的規(guī)則繼承A,B,C的屬性,確定各基類的成
3、員在派生類中的訪問權(quán)限。6(2)多重繼承派生類的構(gòu)造函數(shù)多重繼承派生類的構(gòu)造函數(shù)形式與單繼承時的構(gòu)造函數(shù)形式基形式與單繼承時的構(gòu)造函數(shù)形式基本相同本相同,只是在初始表中包含多個基類構(gòu)造函數(shù)包含多個基類構(gòu)造函數(shù)。如:派生類構(gòu)造函數(shù)名派生類構(gòu)造函數(shù)名(總參數(shù)表列) : 基類基類1構(gòu)造函數(shù)構(gòu)造函數(shù)(參數(shù)表列), 基類基類2構(gòu)造函數(shù)構(gòu)造函數(shù)(參數(shù)表列參數(shù)表列), 基類基類3構(gòu)造函數(shù)構(gòu)造函數(shù) (參數(shù)表列) 派生類中新增數(shù)成員據(jù)成員初始化語句派生類中新增數(shù)成員據(jù)成員初始化語句 派生類構(gòu)造函數(shù)的執(zhí)行順序?yàn)榕缮悩?gòu)造函數(shù)的執(zhí)行順序?yàn)? 先調(diào)用基類的構(gòu)造函數(shù)基類的構(gòu)造函數(shù),再執(zhí)行派生類構(gòu)造函數(shù)的函數(shù)體。調(diào)用基類
4、構(gòu)造函數(shù)的順序是按照聲明派生類時基類出現(xiàn)的順序按照聲明派生類時基類出現(xiàn)的順序。排列順序任意7(2)多重繼承派生類的構(gòu)造函數(shù)例1(P176的例5.8) 聲明一個教師(Teacher)類和一個學(xué)生(Student)類,用多重繼承的方式聲明一個多重繼承的方式聲明一個研究研究生生(Graduate)派生類。 教師類中包括數(shù)據(jù)成員name(姓名)、age(年齡)、title(職稱)。 學(xué)生類中包括數(shù)據(jù)成員name1(姓名)、age(性別)、score(成績)。 在定義派生類對象時給出初始化的數(shù)據(jù),然后輸出這些數(shù)據(jù)。8(2)多重繼承派生類的構(gòu)造函數(shù)#include #include using names
5、pace std;class Teacher /聲明類聲明類Teacher(教師教師) public: /公用部分公用部分 Teacher(string nam,int a, string t)/構(gòu)造函數(shù)構(gòu)造函數(shù) name=nam; age=a; title=t; void display( ) /輸出教師有關(guān)數(shù)據(jù)輸出教師有關(guān)數(shù)據(jù) coutname:nameendl; coutageageendl; couttitle:titleendl; protected: /保護(hù)部分保護(hù)部分 string name; int age; string title; /職稱職稱;12139(2)多重繼承派生
6、類的構(gòu)造函數(shù)class Student /定義類Student(學(xué)生) public: Student(char nam,char s,float sco) strcpy(name1,nam); sex=s; score=sco; /構(gòu)造函數(shù) void display1( ) /輸出學(xué)生有關(guān)數(shù)據(jù) coutname:name1endl; coutsex:sexendl; coutscore:scoreendl; protected: /保護(hù)部分 string name1; char sex;float score; /成績 ;121310(2)多重繼承派生類的構(gòu)造函數(shù)class Graduate
7、 : public Teacher,public Student /聲明多重繼承的派生類Graduate public: Graduate(string nam,int a,char s, string t,float sco,float w): Teacher(nam,a,t),Student(nam,s,sco),wage(w) void show( ) /輸出研究生的有關(guān)數(shù)據(jù) coutname:nameendl; coutage:ageendl; coutsex:sexendl; coutscore:scoreendl; couttitle:titleendl; coutwages:wa
8、geendl; private: float wage; /工資 ;1211(2)多重繼承派生類的構(gòu)造函數(shù)int main( ) Graduate grad1(Wang-li,24,f, assistant, 89.5,1234.5); grad1.show( ); return 0;程序運(yùn)行結(jié)果如下程序運(yùn)行結(jié)果如下: name: Wang-li age: 24sex:fscore: 89.5 title: assistancewages: 1234.5 1112(2)多重繼承派生類的構(gòu)造函數(shù)注意:注意:在兩個基類中分別用name和name1來代表姓名,其實(shí)這是同一個人的名字。在兩個基類中都使
9、用同一個數(shù)據(jù)成員名name?10在show函數(shù)中引用數(shù)據(jù)成員時指明其作用域,如:coutname:Teacher:nameendl;這就是唯一的,不致引起二義性的方法。這就是唯一的,不致引起二義性的方法??梢园l(fā)現(xiàn)一個問題: 在多重繼承時,從不同的基類中會繼承一些重復(fù)的數(shù)據(jù)。如果有多個基類,問題會更突出。在設(shè)計(jì)派生類時如果有多個基類,問題會更突出。在設(shè)計(jì)派生類時要細(xì)致考慮其數(shù)據(jù)成員,盡量減少數(shù)據(jù)冗余。要細(xì)致考慮其數(shù)據(jù)成員,盡量減少數(shù)據(jù)冗余。13(3)多重繼承引起的二義性問題這些重復(fù)的數(shù)據(jù)或者同名的成員使用不當(dāng),則:會產(chǎn)這些重復(fù)的數(shù)據(jù)或者同名的成員使用不當(dāng),則:會產(chǎn)生的二義性生的二義性(ambig
10、uous)問題。問題。進(jìn)一步討論:如果類A和類B中都有成員函數(shù)display和數(shù)據(jù)成員a,類C是類A和類B的直接派生類。分別討論下列3種情況: (a) 兩個基類有同名成員。兩個基類有同名成員。如圖1所示。查看如下程序:圖114(3)多重繼承引起的二義性問題class Apublic: int a; void display( );class Bpublic: int a; void display( );class C :public A,public Bpublic : int b; void show(); int main( ) C c1; c1.a=3; c1.display(); r
11、eturn 0; 因?yàn)椋壕幾g系統(tǒng)因?yàn)椋壕幾g系統(tǒng)無法判別無法判別要訪問的是哪一基類的成員要訪問的是哪一基類的成員c1.A:a=3; c1.A:display();程序編譯程序編譯出錯出錯15(3)多重繼承引起的二義性問題為清楚起見,圖1應(yīng)改用圖2的形式表示。 圖216(3)多重繼承引起的二義性問題(b) 兩個基類和派生類兩個基類和派生類三者都有同名成員三者都有同名成員。將上面的C類聲明改為class C :public A,public B int a; void display();如圖3所示。即有3個a,3個display函數(shù)。圖317(3)多重繼承引起的二義性問題如果: int main(
12、 ) C c1; c1.a=3; c1.display(); return 0; 程序能通過編譯,也程序能通過編譯,也可正常運(yùn)行。可正常運(yùn)行。訪問的是派生類訪問的是派生類C中中的成員的成員。訪問同名成員的規(guī)則訪問同名成員的規(guī)則: 基類的同名成員在派生類中被屏蔽,成為“不可見”的,或者說,派生類新增加的同名成員覆蓋了基類中派生類新增加的同名成員覆蓋了基類中的同名成員的同名成員。18(3)多重繼承引起的二義性問題請注意請注意: 不同的成員函數(shù),只有在函數(shù)名和參數(shù)個數(shù)相同、類型相匹配的情況下才發(fā)生同名覆蓋,如果只有函數(shù)名相同而參數(shù)不同,不會發(fā)生同名覆蓋,而屬于函數(shù)重載。要在派生類外訪問基類要在派生類
13、外訪問基類A中的成員,中的成員,應(yīng)指明作用域應(yīng)指明作用域A,寫成以下形式: c1.A:a=3; /表示是派生類對象c1中的基類A中的數(shù)據(jù)成員ac1.A:display(); /表示是派生類對象c1中的基類A中的成員函數(shù)display19(3)多重繼承引起的二義性問題(c) 如果類A和類B是從同一個基類派生的,如圖4所示。class Npublic: int a; void display() coutA:a=”aendl;class A: public Npublic: int a1;class B: public Npublic: int a2;圖4class C : public A,pu
14、blic Bpublic : int a3; ;20(3)多重繼承引起的二義性問題怎樣才能訪問類怎樣才能訪問類A中從基類中從基類N繼承下來的成員呢?繼承下來的成員呢?應(yīng)當(dāng)通過通過類類N的直接派生類名的直接派生類名來指出要訪問的是類來指出要訪問的是類N的的哪一個派生類中的基類成員哪一個派生類中的基類成員。如:c1.A:a=3; c1.A:display();c1.a=3;c1.display( );或c1.N:a=3; c1.N:display();顯然不行!因?yàn)檫@樣依然無法區(qū)別是類A中從基類N繼承下來的成員,還是類B中從基類N繼承下來的成員。21(4)虛基類從上面的介紹可知: 如果一個派生類有
15、多個直接基類,而這些直接基類又有一個共同的基類,則在最終的派在最終的派生類中生類中會保留該間接共同基類數(shù)據(jù)成員的多份同名會保留該間接共同基類數(shù)據(jù)成員的多份同名成員成員。 如圖7和圖8所示。22(4)虛基類圖7圖8在引用這些同名的成員時,必須在派生類對象名后增加直接基類名,以避免產(chǎn)生二義性。如:c1.A:display( )。23(4)虛基類在一個類中保留間接共同基類的多份同名成員,這種現(xiàn)象是人們不希望出現(xiàn)的。a. 虛基類的作用虛基類的作用C+提供提供虛基類虛基類(virtual base class)的方法,的方法,使得在繼使得在繼承間接共同基類時只保留一份成員。承間接共同基類時只保留一份成員
16、。聲明虛基類的聲明虛基類的一般形式一般形式為為:class 派生類名派生類名: virtual 繼承方式繼承方式 基類名基類名24(4)虛基類現(xiàn)在,將類A聲明為虛基類,方法如下: class A/聲明基類A ;class B :virtual public A /聲明類B是類A的公用派生類,A是B的虛基類 ;class C :virtual public A /聲明類C是類A的公用派生類,A是C的虛基類 ;注意注意: 虛基類并不是在聲明基類時聲明的,而是在聲明派生類時,虛基類并不是在聲明基類時聲明的,而是在聲明派生類時,指定繼承方式時聲明的。指定繼承方式時聲明的。25(4)虛基類經(jīng)過這樣的聲明
17、后,當(dāng)基類通過多條派生路徑被一個經(jīng)過這樣的聲明后,當(dāng)基類通過多條派生路徑被一個派生類繼承時,該派生類只繼承該基類一次。派生類繼承時,該派生類只繼承該基類一次。D類int data;int data_b;int data_cvoid fun( );int data_d;void fun_d( );26(4)虛基類b. 虛基類的初始化如果在虛基類中定義了帶參數(shù)的構(gòu)造函數(shù),而且沒有定義默認(rèn)構(gòu)造函數(shù),則在其所有派生類(包括直接派生或間接派生的派生類)中,通過構(gòu)造函數(shù)的初始化表對虛基類進(jìn)行初始化。例如class A/定義基類A A(int i) /基類構(gòu)造函數(shù),有一個參數(shù);class B :virtua
18、l public A /A作為B的虛基類 B(int n):A(n) /B類構(gòu)造函數(shù),在初始化表中對虛基類初始化 ;class C :virtual public A /A作為C的虛基類 C(int n):A(n) /C類構(gòu)造函數(shù),在初始化表中對虛基類初始化;class D :public B,public C /類D的構(gòu)造函數(shù),在初始化表中對所有基類初始化 D(int n):A(n),B(n),C(n) ; 27(4)虛基類注意: 在定義類D的構(gòu)造函數(shù)時,與以往使用的方法有所不同。規(guī)定規(guī)定: 在最后的派生類中不僅要負(fù)責(zé)對其直接基類進(jìn)行在最后的派生類中不僅要負(fù)責(zé)對其直接基類進(jìn)行初始化,還要負(fù)責(zé)
19、對虛基類初始化。初始化,還要負(fù)責(zé)對虛基類初始化。C+編譯系統(tǒng)只執(zhí)行最后的派生類對虛基類的構(gòu)造函數(shù)編譯系統(tǒng)只執(zhí)行最后的派生類對虛基類的構(gòu)造函數(shù)的調(diào)用,而忽略虛基類的其他派生類的調(diào)用,而忽略虛基類的其他派生類(如類如類B和類和類C) 對虛基類的構(gòu)造函數(shù)的調(diào)用,這就保證了虛基類的對虛基類的構(gòu)造函數(shù)的調(diào)用,這就保證了虛基類的數(shù)據(jù)成員不會被多次初始化。數(shù)據(jù)成員不會被多次初始化。282虛基類的簡單應(yīng)用舉例例2(P185例5.9)在例5.8(P176)的基礎(chǔ)上,在Teacher類和Student類之上增加一個共同的基類Person,如所示。作為人員的一些基本數(shù)據(jù)都放在Person中,在Teacher類和St
20、udent類中再增加一些必要的數(shù)據(jù)。圖11292虛基類的簡單應(yīng)用舉例#include #include using namespace std;/聲明公共基類Personclass Personpublic: Person(string nam,char s,int a)/構(gòu)造函數(shù) name=nam;sex=s;age=a;protected: /保護(hù)成員 string name; char sex; int age;302虛基類的簡單應(yīng)用舉例/聲明Person的直接派生類Teacherclass Teacher: virtual public Person /聲明Person為公用繼承的虛基
21、類public: Teacher(string nam,char s,int a, string t):Person(nam,s,a)/構(gòu)造函數(shù) title=t; protected: /保護(hù)成員 string title; /職稱;312虛基類的簡單應(yīng)用舉例/聲明Person的直接派生類Studentclass Student: virtual public Person /聲明Person為公用繼承的虛基類public:Student(string nam,char s,int a,float sco) /構(gòu)造函數(shù) :Person(nam,s,a),score(sco) /初始化表prot
22、ected: /保護(hù)成員 float score; /成績 ;322虛基類的簡單應(yīng)用舉例class Graduate:public Teacher,public Student /Teacher和Student為直接基類public:Graduate(string nam,char s,int a, string t,float sco,float w):Person(nam,s,a),Teacher(nam,s,a,t),Student(nam,s,a,sco),wage(w) void show( ) /輸出研究生的有關(guān)數(shù)據(jù) coutname:nameendl; coutage:ageen
23、dl; coutsex:sexendl; coutscore:scoreendl; couttitle:titleendl; coutwages:wageendl; private: float wage; /工資 ;332虛基類的簡單應(yīng)用舉例/主函數(shù) int main( ) Graduate grad1(Wang-li,f,24, assistant, 89.5,1234.5); grad1.show( ); return 0;運(yùn)行結(jié)果為name: Wang-li age:24sex:fscore:89.5title:assistantwages:1234.5342虛基類的簡單應(yīng)用舉例可以看
24、到可以看到: 使用多重繼承時要十分小心,經(jīng)常會出現(xiàn)二使用多重繼承時要十分小心,經(jīng)常會出現(xiàn)二義性問題。義性問題。許多專業(yè)人員認(rèn)為許多專業(yè)人員認(rèn)為: 不要提倡在程序中使用多重繼承不要提倡在程序中使用多重繼承,只有在比較簡單和不易出現(xiàn)二義性的情況或?qū)嵲诒匾獣r才使用多重繼承,能用單一繼承解決的問題就不要使用多重繼承。也是由于這個原因,有些面向?qū)ο蟮某绦蛟O(shè)計(jì)語言也是由于這個原因,有些面向?qū)ο蟮某绦蛟O(shè)計(jì)語言(如如Java,Smalltalk)并不支持多重繼承。并不支持多重繼承。35*3基類與派生類的轉(zhuǎn)換基類與派生類的轉(zhuǎn)換由于派生類中包含從基類繼承的成員,因此可以將派生類的值賦給基類對象,在用到基類對象的時
25、候可以用其子類對象代替。具體表現(xiàn)在以下幾個方面: (a) 派生類對象可以向基類對象賦值派生類對象可以向基類對象賦值??梢杂米宇?即公用派生類)對象對其基類對象賦值。如A a1; /定義基類A對象a1B b1; /定義類A的公用派生類B的對象b1a1=b1; /用派生類B對象b1對基類對象a1賦值在賦值時舍棄派生類自己的成員。36*3基類與派生類的轉(zhuǎn)換基類與派生類的轉(zhuǎn)換實(shí)際上,所謂賦值只是對數(shù)據(jù)成員賦值,對成員函數(shù)不存在賦值問題。 注意注意: 賦值后不能企圖通過對象a1去訪問派生類對象b1的成員,因?yàn)閎1的成員與a1的成員是不同的。特別注意特別注意:只能用子類對象對其基類對象賦值,而不能用基類對
26、象對其子類對象賦值。因?yàn)榛悓ο蟛话缮惖某蓡T,無法對派生類的成員賦值。同理,同一基類的不同派生類對象之間也不能賦值。A a1; B b1; / B是A的公用派生a1=b1;37*3基類與派生類的轉(zhuǎn)換基類與派生類的轉(zhuǎn)換(b) 派生類對象可以替代基類對象,向基類對象的引用進(jìn)行賦值或初始化。如已定義了基類A對象a1,可以定義a1的引用變量:A a1; /定義基類A對象a1B b1; /定義公用派生類B對象b1A & r=a1; /定義基類A對象的引用變量r,并用a1對其初始化這時,引用變量r是a1的別名,r和a1共享同一段存儲單元。若:A& r=b1;/定義基類A對象的引用變量
27、r,并用派生類B對象b1對其初始化或者保留上面第3行“A& r=a1;”,而對r重新賦值:r=b1;注意注意: 此時r并不是b1的別名,也不與b1共享同一段存儲單元。它只是b1中基類部分的別名,r與b1中基類部分共享同一段存儲單元,r與b1具有相同的起始地址。38*3基類與派生類的轉(zhuǎn)換基類與派生類的轉(zhuǎn)換(c) 如果函數(shù)的參數(shù)是基類對象或基類對象的引用,相應(yīng)的實(shí)參可以用子類對象。如有一函數(shù)fun: void fun(A& r) /形參是類A的對象的引用變量 coutr.numendl; 函數(shù)的形參是類函數(shù)的形參是類A的對象的引用變量的對象的引用變量,本來實(shí)參應(yīng)該為A類的對象。在調(diào)
28、用在調(diào)用fun函數(shù)時可以用派生類函數(shù)時可以用派生類B的對象的對象b1作實(shí)參作實(shí)參: fun(b1); /(假設(shè)B是A的派生類)則結(jié)果:輸出類B的對象b1的基類數(shù)據(jù)成員num的值。39*3基類與派生類的轉(zhuǎn)換基類與派生類的轉(zhuǎn)換(d) 派生類對象的地址可以賦給指向基類對象的指針變派生類對象的地址可以賦給指向基類對象的指針變量量,也就是說,指向基類對象的指針變量也可以指向派生類對象。比如:(參見 189例5.10) class Student/聲明Student類public: Student(int, string,float); void display( ); private: int num;
29、 string name; float score;class Graduate:public Studentpublic: Graduate(int, string ,float,float); void display( ); private: float pay; /工資;40*3基類與派生類的轉(zhuǎn)換基類與派生類的轉(zhuǎn)換void Student:display( ) /定義輸出函數(shù) coutendlnum:numendl; coutname:nameendl; coutscore:scoreendl;void Graduate:display() /定義輸出函數(shù) Student:displa
30、y(); /調(diào)用Student類的display函數(shù) coutpay=paydisplay( ); /調(diào)用stud1.display函數(shù) pt=&grad1; /指針指向grad1 pt-display( ); /調(diào)用grad1.display函數(shù) 通過指向基類對象的指針,只能訪問派生類中的基類成員,而不能訪問派生類增加的成員num:1001name:Liscore:87.5num:2001name:wangscore:98.541需要訪問,使用虛函數(shù)和多態(tài)性 424繼承與組合繼承與組合前面講過: 在一個類中可以用類對象作為數(shù)據(jù)成員,即子對象子對象。對象成員的類型可以是本派生類的基類,也可以是另外一個已定義的類。一個類中以另一個類的對象作
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 個人土地?zé)o償贈與合同范本
- 個人家政保潔合同范本
- 制定合同范本 作用
- fidic條件合同范本
- 買賣延期合同范本
- 醫(yī)用機(jī)甲租賃合同范本
- 凈水設(shè)備售賣合同范本
- 勞動合同范本藥店
- 出租和諧公寓合同范本
- 修建垃圾臺合同范本
- 政企業(yè)務(wù)部門培訓(xùn)
- 高考全國卷有機(jī)化學(xué)大題
- 2024年高考?xì)v史:全3冊核心知識梳理和大事年表
- 創(chuàng)意改變生活智慧樹知到期末考試答案2024年
- 蘇教版三年級下冊數(shù)學(xué)全冊作業(yè)設(shè)計(jì)
- 4.《昆蟲備忘錄》 課件
- 非標(biāo)設(shè)備方案
- 2024壓縮空氣儲能電站可行性研究報(bào)告編制規(guī)程
- 教師如何進(jìn)行跨學(xué)科教學(xué)
- 數(shù)學(xué)-山東省濟(jì)寧市2023屆高三第一次模擬考試
- 2016-2023年蘇州信息職業(yè)技術(shù)學(xué)院高職單招(英語/數(shù)學(xué)/語文)筆試歷年考點(diǎn)試題甄選合集含答案解析
評論
0/150
提交評論