《CC++語言程序設(shè)計》課件第11章 派生類與繼承_第1頁
《CC++語言程序設(shè)計》課件第11章 派生類與繼承_第2頁
《CC++語言程序設(shè)計》課件第11章 派生類與繼承_第3頁
《CC++語言程序設(shè)計》課件第11章 派生類與繼承_第4頁
《CC++語言程序設(shè)計》課件第11章 派生類與繼承_第5頁
已閱讀5頁,還剩40頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

第十一章派生類與繼承11.1類的繼承與派生11.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)11.3多重繼承11.4虛基類11.5小結(jié)

繼承是C++的一種重要機制,是程序可重用與擴充的一個重要方面。這一機制使得程序員可以在已有類的基礎(chǔ)上建立新類。從而擴展程序功能、體現(xiàn)類的多態(tài)性特征。11.1類的繼承與派生自然世界的類概念是抽象的,類的下面還有子類,子類繼承父類的各種特征。面向?qū)ο蟪绦蛟O(shè)計允許你聲明一個新類作為另一個類的派生。派生類(也稱子類)可以聲明新的屬性(成員)和新的操作(成員函數(shù))。繼承可以讓你重用父類代碼,專注于為子類編寫新代碼。我們稱最初的類為基類,根據(jù)它生成的類稱為派生類(子類),這種派生可以是多層次的。11.1.1繼承與派生的概念哺乳動物類貓類犬類波斯貓安哥拉貓西施犬沙皮犬為什么要使用繼承?例如:classperson{private:charname[10];intage;charsex;public:voidprint();}classemployee{private:charname[10];intage;charsex;chardepartment[20];floatsalary;public:voidprint();}11.1.2派生類的聲明聲明一個派生類的一般格式為:class派生類名:派生方式基類名{ //派生類新增的數(shù)據(jù)成員和成員函數(shù)}“保護成員”是由protected聲明的類成員。保護成員不能被外界引用,這點和私有成員類似,但它可以被派生類的成員函數(shù)引用。下面用派生關(guān)系改寫person和employee類?;恈lassperson{private:charname[10];intage;charsex;public:voidprint();}派生類classemployee:publicperson{private:chardepartment[20];floatsalary;public://…}派生方式公有派生classemployee:publicperson{//…}私有派生classemployee:privateperson{//…}保護派生classemployee:protectedperson{//…}特點:公有繼承:基類的公有成員和保護成員作為派生類的成員時,它們都保持原有的狀態(tài),而基類的私有成員仍然是私有的。保護繼承:基類的所有公有成員和保護成員都成為派生類的保護成員,并且只能被它的派生類成員函數(shù)或友元訪問,基類的私有成員仍然是私有的。私有繼承:基類的公有成員和保護成員都作為派生類的私有成員,并且不能被這個派生類的子類所訪問。缺省繼承方式為private.繼承方式基類特性派生類特性公有繼承PublicprotectedprivatePublicProtected不可訪問私有繼承PublicprotectedprivatePrivatePrivate不可訪問保護繼承PublicprotectedprivateProtectedProtected不可訪問例11.1派生類對基類的訪問特性。#include<iostream.h>classA{public: voidf1();protected: intj1;private: inti1;};classB:publicA{public: voidfn2();protected: intj2;private: inti2;};classC:publicB{

public: voidf3();};問題:1.B中成員函數(shù)f2()能否訪問基類A中的成員:f1(),i1,j1?2.B的對象b1能否訪問A的成員?3.C的成員函數(shù)f3()能否訪問直接基類B中的成員:f2(),i2,j2?4.派生類C的對象c1是否可以訪問直接基類B的成員?能否訪問間接其類A的成員:f1(),i1,j1?回答:1.可以訪問f1(),j1,不可訪問i1;2.可以訪問f1(),不可訪問i1,j1;3.可以訪問f2(),j2,f1(),j1,不可訪問i1,i2;4.可以訪問f2(),f1(),其他的都不可以訪問;結(jié)論:在公有繼承時,派生類的成員函數(shù)可訪問基類中的公有成員和保護成員;派生類的對象僅可訪問基類中的公有成員?!纠?1.2】私有派生類對基類成員的訪問。

#include<iostream.h> classbase{//聲明一個基類 intx; public: voidsetx(intn){x=n;} voidshowx()

{cout<<x<<endl;} }; classderived:privatebase{//聲明一個私有派生類 inty; public: voidsety(intn){y=n;} voidshowxy()

{cout<<x<<y<<endl;}

//非法,派生類不能訪問基類的私有成員 };【例11.3】私有派生類對基類成員的訪問。#include<iostream.h>classbase{intx;public:voidsetx(intn){x=n;}voidshowx()

{cout<<x<<endl;}};classderived:privatebase{inty;public:voidsety(intn){y=n;}voidshowy()

{cout<<y<<endl;}};main(){derivedobj;obj.setx(10);//非法

obj.sety(20);//合法

obj.showx();//非法

obj.showy();//合法

return0;}如果將derived類改為公有派生,則main函數(shù)中的調(diào)用合法否?(例11.4)如果將derived類改為保護派生,則main函數(shù)中的調(diào)用合法否?(例11.4)思考在派生類中聲明的名字可以支配基類中聲明的同名的名字。如果在派生類的成員函數(shù)中直接使用該名字的話,則表示使用派生類中聲明的名字,例如: classX{public: intf();};

classY:publicX{public: intf(); intg();}; voidY::g(){f();//表示被調(diào)用的函數(shù)是Y::f(),而不是X::f()}

11.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)

基類都有顯示的或隱式的構(gòu)造函數(shù)和析構(gòu)函數(shù)。當(dāng)創(chuàng)建一個派生類對象時,如何調(diào)用基類的構(gòu)造函數(shù)對基類數(shù)據(jù)初始化,以及在撤銷派生類對象時,又如何調(diào)用基類的析構(gòu)函數(shù)對基類對象的數(shù)據(jù)成員進行善后處理,是本節(jié)所要討論的內(nèi)容。11.2.1構(gòu)造和析構(gòu)的次序通常情況下,當(dāng)創(chuàng)建派生類時,首先執(zhí)行基類的構(gòu)造函數(shù),隨后再執(zhí)行派生類的構(gòu)造函數(shù);當(dāng)撤銷派生類對象時,則先執(zhí)行派生類的析構(gòu)函數(shù),隨后再執(zhí)行基類的析構(gòu)函數(shù)。參見例11.6【例11.6】掌握基類和派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行順序。#include<iostream.h>classbase{public: base() {cout<<"基類的構(gòu)造函數(shù)"<<endl;} ~base() {cout<<"基類的析構(gòu)函數(shù)"<<endl;}};classderive:publicbase{public: derive() {cout<<"派生類的構(gòu)造函數(shù)"<<endl;} ~derive() {cout<<"派生類類的析構(gòu)函數(shù)"<<endl;}};main(){ deriveop; return0;}11.2.2派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)的構(gòu)造規(guī)則派生類構(gòu)造函數(shù)的一般格式:在定義派生類對象時,構(gòu)造函數(shù)的執(zhí)行順序如下:(1)基類的構(gòu)造函數(shù)(2)對象成員的構(gòu)造函數(shù)(3)派生類的構(gòu)造函數(shù)例11.7派生類構(gòu)造函數(shù)名(參數(shù)表):基類構(gòu)造函數(shù)名(參數(shù)表),對象成員名1(參數(shù)表),…,對象成員名n(參數(shù)表)

{派生類中其它數(shù)據(jù)成員初始化}【例11.7】派生類構(gòu)造函數(shù)給基類構(gòu)造函數(shù)傳遞參數(shù)。#include<iostream.h> classbase{ intx; public: base(inta)

{cout<<"基類的構(gòu)造函數(shù)"<<endl;

x=a; }

~base()

{cout<<"基類的析構(gòu)函數(shù)"<<endl;}

voidshowx(){cout<<x<<endl;} };classderived:publicbase{ inty; public: derived(inta,intb):base(a)

//派生類的構(gòu)造函數(shù),要綴上基類的構(gòu)造函數(shù)

{ cout<<"派生類的構(gòu)造函數(shù)"<<endl; y=b; } ~derived(){cout<<"派生類的析構(gòu)函數(shù)"<<endl;} voidshowy() {cout<<y<<endl;} }; voidmain() {derivedobj(10,20); obj.showx(); obj.showy(); return0; }含有對象成員的派生類構(gòu)造函數(shù)當(dāng)派生類中含有對象成員時,派生類必須負(fù)責(zé)該對象成員的構(gòu)造,其構(gòu)造函數(shù)的一般形式為:

派生類構(gòu)造函數(shù)名(參數(shù)表):基類構(gòu)造函數(shù)名(參數(shù)表),對象成員名1(參數(shù)表),…,對象成員名n(參數(shù)表){ //…}【例11.8】含有對象成員的派生類構(gòu)造函數(shù)的執(zhí)行情況

#include<iostream.h> classbase{ intx; public: base(inta) { cout<<"基類的構(gòu)造函數(shù)"<<endl; x=a; } ~base()

{cout<<"基類的析構(gòu)函數(shù)"<<endl;} voidshowx() {cout<<x<<endl;} };

classderived:publicbase{ public: based; //d為基類對象,作為派生類的對象成員

derived(inta,intb):base(a),d(b)

//派生類的構(gòu)造函數(shù),綴上基類構(gòu)造函數(shù)

//和對象成員的構(gòu)造函數(shù)

{cout<<"派生類的構(gòu)造函數(shù)"<<endl; }

~derived(){cout<<"派生類的析構(gòu)函數(shù)"<<endl;} }; voidmain() {

derivedobj(10,20); obj.showx(); obj.d.showx(); }說明當(dāng)基類的構(gòu)造函數(shù)不帶參數(shù)時,派生類不一定需要定義構(gòu)造函數(shù),然而當(dāng)基類的構(gòu)造函數(shù)那怕只帶有一個參數(shù),它所有的派生類都必須定義構(gòu)造函數(shù),甚至所定義的派生類的構(gòu)造函數(shù)的函數(shù)體有可能為空,僅僅起到參數(shù)傳遞作用。若基類使用缺省構(gòu)造函數(shù)或不帶參數(shù)的構(gòu)造函數(shù),則在派生類中定義構(gòu)造函數(shù)時可略去,此時若派生類也不需要構(gòu)造函數(shù),則可以不定義構(gòu)造函數(shù)。如果派生類的基類也是一個派生類,則每個派生類只需要負(fù)責(zé)直接基類的構(gòu)造。由于析構(gòu)函數(shù)是不帶參數(shù)的,在派生類中是否要定義析構(gòu)函數(shù)與它所屬的基類無關(guān)。11.3多重繼承多重繼承:一個派生類具有多個基類。在多重繼承中,公有繼承和私有繼承對于基類成員在派生類中的可訪問性與單繼承相同。玩具車玩具車class派生類名:繼承方式1基類名1,…,繼承方式n基類名n{派生類新定義成員};11.3.1多重繼承的聲明例11.9聲明多重派生。#include<iostream.h>classX{ inta;public: voidsetX(intx) {a=x;} voidshowX(){cout<<"a="<<a<<endl;}};classY{ intb;public: voidsetY(inty) {b=y;} voidshowY() {cout<<"b="<<b<<endl;}};classZ:publicX,privateY{ intc;public: voidsetZ(intx,inty) { c=x; setY(y); } voidshowZ() { showY(); cout<<"c="<<c<<endl; }};voidmain(){ Zobj; obj.setX(3); obj.showX(); //obj.setY(4); //obj.showY(); obj.setZ(6,8); obj.showZ();}二義性對基類成員的訪問必須是無二義性的。消除下例中的二義性,可寫為obj.X::f();//調(diào)用類X的f()obj.X::f();//調(diào)用類Y的f()例11.10多重繼承時,對基類訪問存在二義性的情況。 #include<iostream.h> classbase1{ public: voidshow(){} }; classbase2{ public: voidshow(){} }; classderive:publicbase1,privatebase2{ public: voidshowderive() {} }; voidmain() { deriveobj; obj.show(); //二義性錯誤,不知調(diào)用的是//base1的show()//還是base2的show()}11.3.2多重繼承的構(gòu)造函數(shù)

多重繼承構(gòu)造函數(shù)定義的一般形式如下:

派生類構(gòu)造函數(shù)名(參數(shù)表):基類構(gòu)造函數(shù)名1(參數(shù)表),基類構(gòu)造函數(shù)名2(參數(shù)表),…,基類構(gòu)造函數(shù)名n(參數(shù)表){ //派生類中其它數(shù)據(jù)成員初始化}【例11.8】含有對象成員的派生類構(gòu)造函數(shù)的執(zhí)行情況。

#include<iostream.h> classbase{ intx; public: base(inta) { cout<<"基類的構(gòu)造函數(shù)"<<endl; x=a; } ~base() {cout<<"基類的析構(gòu)函數(shù)"<<endl;} voidshowx() {cout<<x<<endl;} };

classderived:publicbase{ public: based;//d為基類對象,作為派生類的對象成員 derived(inta,intb):base(a),d(b)

//派生類的構(gòu)造函數(shù),綴上基類構(gòu)造函數(shù) //和對象成員的構(gòu)造函數(shù) {cout<<"派生類的構(gòu)造函數(shù)"<<endl; }

~derived(){cout<<"派生類的析構(gòu)函數(shù)"<<endl;} }; voidmain() {derivedobj(10,20); obj.showx(); obj.d.showx(); }11.4虛基類當(dāng)引用派生類的成員時,首先在派生類自身的作用域中尋找這個成員,如果沒有找到,則在它的基類中尋找。如果一個派生類是從多個基類派生出來的,而這些基類又有一個共同的基類,則在這個派生類中訪問這個共同的基類中的成員時,可能會產(chǎn)生二義性。virtual關(guān)鍵字,同繼承方式關(guān)鍵字的先后順序無關(guān)緊要?!纠?1.12】多重派生產(chǎn)生二義性的情況#include<iostream.h>classbase{protected: inta;public: base() {a=5;}};classbase1:publicbase{public: base1() {cout<<"base1a="<<a<<endl;}};classbase2:publicbase{public: base2() {cout<<"base2a="<<a<<endl;}};classderived:publicbase1,publicbase2{public: derived() {cout<<"de

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論