c++課件第十一章繼承與派生_第1頁
c++課件第十一章繼承與派生_第2頁
c++課件第十一章繼承與派生_第3頁
c++課件第十一章繼承與派生_第4頁
c++課件第十一章繼承與派生_第5頁
已閱讀5頁,還剩19頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第11章 繼承和派生11.1繼承與派生的概念 圖11.1 圖11.2本書中的約定,箭頭表示繼承的方向,從派生類指向基類。圖11.3圖11.4圖11.511.2派生類的聲明方式class Studentpublic:void get_value()cinnumnamesex;void display( )coutnum: numendl;coutname: nameendl;coutsex: sexageaddr;void display_1()coutage:ageendl; coutaddress: addrendl;private: int age; string addr;繼承方式有:p

2、ublic(公有),private(私有),protected(保護)11.3派生類的構成 圖11.611.4派生類成員的訪問屬性11.4.1公用繼承 例11.1公有繼承實例。#include #include using namespace std;class Studentpublic:void get_value()cinnumnamesex;void display( )coutnum: numendl;coutname: nameendl;coutsex: sexageaddr;void display_1() /coutnum: numendl; /企圖引用基類的私有成員,錯誤 /

3、coutname: nameendl; /企圖引用基類的私有成員,錯誤 /coutsex: sexendl; /企圖引用基類的私有成員,錯誤 coutage: ageendl; /引用派生類的私有成員,正確 coutaddress: addrendl; /引用派生類的私有成員,正確private: int age; string addr;int main()Student1 stud1;stud1.get_value();stud1.get_value_1();stud1.display();stud1.display_1();return 0;1001 huang F 18 Beijing

4、num: 1001name: huangsex: Fage: 18address: Beijing#includeclass Locationprivate: int X,Y;public:int GetX()return X;int GetY()return Y;int Z;protected:int P;class Rectangle:public Locationprivate: int Height,Width;public:/int GetHH()X=5;return Height;/在公有派生中基類的私有成員在派生類中是不可訪問的 int GetH()coutGetX()endl;

5、Z=88;return Height;/在公有派生中基類的公有成員在派生類中還是公有成員int GetW()P=55;return Width;/在公有派生中基類的保護成員在派生類中還是保護成員;class test:public Rectanglevoid fun2()P=89;/P在test類中是可訪問的void fun1()Z=66;/Z在test類中是可訪問的;void fun()Rectangle r; /定義對象rint Xvalue=r.GetX(); /使用基類返回r的X值int h=r.GetH(); /通過派生類返回r的H值r.Z=99; /在公有派生中基類的公有成員在/派

6、生類中還是公有成員 r.P=109;/在公有派生中基類的保護成員/在派生類中還是保護成員void main()fun();11.4.2私有繼承 圖11.7例11.2 私有繼承實例#include #include using namespace std;#include #include using namespace std;class Studentpublic:void display( ) coutnum: numendl;coutname: nameendl;coutsex: sexendl;private :int num;string name;char sex; class S

7、tudent1: private Studentpublic:void display_1() display();/調用基類公有成員函數,/在派生類中成為私有成員coutage: ageendl;/引用派生類的私有成員,正確 coutaddress: addrendl;/引用派生類的私有成員,正確private:int age; string addr; ;int main()Student1 stud1;/stud1.display();/錯誤stud1.display_1();return 0;#includeclass Locationprivate: int X,Y;public:i

8、nt GetX()return X;int GetY()return Y;int Z;protected:int P;class Rectangle:private Locationprivate: int Height,Width;public:/int GetHH()X=5;return Height;/在私有派生中基類的私有成員在派生類中是不可訪問的int GetH()coutGetX()endl;Z=88;return Height;/在私有派生中基類的公有成員在派生類中是私有成員int GetW()P=55;return Width;/在私有派生中基類的保護成員在派生類中是私有成員;

9、class test:public Rectangle/void fun2()P=89;/P在test類中是不可訪問的/void fun1()Z=66;/Z在test類中是不可訪問的;void fun()Rectangle r; /定義對象r/int Xvalue=r.GetX(); /使用基類返回r的X值int h=r.GetH(); /通過派生類返回r的H值 /r.Z=99;/在私有派生中基類的公有成員在派生類中是私有成員/r.P=109;/在私有派生中基類的保護成員在派生類中還是私有成員void main()fun();11.4.3保護成員和保護繼承例11.3在派生類中引用保護成員。#i

10、nclude #include using namespace std;class Student /聲明基類public: /基類公用成員 void display( );protected : /基類保護成員 int num; string name; char sex;void Student:display( )coutnum: numendl; coutname: nameendl; coutsex: sexendl;class Student1: protected Student /用protected繼承方式聲明一個派生類public:void display1( );priv

11、ate:int age; string addr;void Student1:display1( )coutnum: numendl; /引用基類的保護成員,合法 coutname: nameendl;/引用基類的保護成員,合法 coutsex: sexendl;/引用基類的保護成員,合法 coutage: ageendl;/引用派生類的私有成員,合法 coutaddress: addrendl;/引用派生類的私有成員,合法int main( )Student1 stud1; /stud1是派生類student2的對象stud1.display1( );/display是派生類中的保護成員函數

12、return 0;#includeclass Locationprivate: int X,Y;public:int GetX()return X;int GetY()return Y;int Z;protected:int P;class Rectangle:protected Locationprivate: int Height,Width;public:/int GetHH()X=5;return Height;/在保護派生中基類的私有成員在派生類中是不可訪問的int GetH()coutGetX()endl;Z=88;return Height;/在保護派生中基類的公有成員在派生類中

13、是保護的int GetW()P=55;return Width;/在保護派生中基類的保護成員在派生類中是保護的;class test:public Rectanglevoid fun2()P=89;void fun1()Z=66;class test_test:public testvoid fun3()P=89;/證明P是保護的void fun4()Z=66;/證明Z是保護的;void fun()Rectangle r; /定義對象rint h=r.GetH(); /通過派生類返回r的H值 /r.Z=99;/在保護派生中基類的公有成員在派生類中是保護的 /r.P=109;/在保護派生中基類的

14、公有成員在派生類中是保護的void main()fun();test t1;/t1.P=90;/錯誤證明P不是公有的/t1.Z=79;/錯誤證明Z不是公有的11.4.4多級派生時的訪問屬性例11.4 多級派生時的訪問屬性class A /基類public:int i;protected:void f2();int j;private:int k;class B: public A /public方式public:void f3( );protected:void f4();private:int m;class C: protected B /protected方式public:void f5

15、();private:int n; i f2 j k基類A派生類B派生類C11.5派生類的構造函數和析構函數11.5.1簡單的派生類的構造函數例11.5 簡單的派生類的構造函數#include #includeusing namespace std;class Student /聲明基類public: /公用部分 Student(int n,string nam,char s )/基類構造函數 num=n; name=nam; sex=s; Student( ) /基類析構函數protected: /保護部分 int num; string name; char sex ; ;class St

16、udent1: public Student/聲明公用派生類studentpublic: Student1(int n,string nam,char s,int a,char ad) : Student(n,nam,s)/派生類構造函數 age=a;/在函數體中只對派生類新增的數據成員初始化 addr=ad; void show( ) coutnum: numendl; coutname: nameendl; coutsex: sexendl; coutage: ageendl; coutaddress: addrendlendl; Student1( ) /派生類析構函數private:

17、/派生類的私有部分 int age; string addr; ; int main( )Student1 stud1(10010,Wang-li,f,19,115 Beijing Road,Shanghai);Student1 stud2(10011,Zhang-fun,m,21,213 Shanghai Road,Beijing);stud1.show( ); /輸出第一個學生的數據stud2.show( ); /輸出第二個學生的數據return 0;num: 10010name: Wang-lisex: fage: 19address: 115 Beijing Road,Shanghai

18、num: 10011name: Zhang-funsex: mage: 21address: 213 Shanghai Road,Beijing圖11.10圖11.1111.5.2有子對象的派生類的構造函數例11.6包含子對象的派生類的構造函數。#include #include using namespace std;class Student /聲明基類public: /公用部分Student(int n,string nam)/基類構造函數 num=n;name=nam;void display() /輸出基類數據成員 coutnum:numendlname:nameendl;prote

19、cted: /保護部分 int num; string name;class Student1: public Student /用public繼承方式聲明派生類studentpublic:Student1(int n,string nam,int n1,string nam1,int a,string ad):Student(n,nam),monitor(n1,nam1) /派生類構造函數 age=a; /在此處只對派生類新增的數據成員初始化 addr=ad; void show( ) coutThis student is:endl;display(); /輸出num和namecoutag

20、e: ageendl;coutaddress: addrendlendl; void show_monitor()/輸出子對象的數據成員 coutendlClass monitor is:endl;monitor.display();/調用基類成員函數 private: /派生類的私有數據 Student monitor; /定義子對象(班長) int age; string addr; ; int main( )Student1 stud1(10010,Wang-li,10001,Li-sun,19,115 Beijing Road,Shanghai);stud1.show( );/輸出第一

21、個學生的數據stud1.show_monitor(); /輸出子對象的數據return 0;This student is:num:10010name:Wang-liage: 19address: 115 Beijing Road,ShanghaiClass monitor is:num:10001name:Li-sun 圖11.12執(zhí)行派生類構造函數的順序是:(1) 調用基類構造函數,對基類數據成員初始化。(2) 調用子對象的構造函數,對子對象的數據成員初始化。(3) 執(zhí)行派生類構造函數,對派生類數據成員初始化。11.5.3多層派生時的構造函數例11.7#include #includeus

22、ing namespace std;class Student /聲明基類public: /公用部分 Student(int n, string nam)/基類構造函數 num=n;name=nam; void display() /輸出基類數據成員 coutnum:numendl;coutname:nameendl; protected: /保護部分 int num; /基類有兩個數據成員 string name;class Student1: public Student/聲明公用派生類Student1 public: Student1(int n,string nam,int a):St

23、udent(n,nam)/派生類構造函數 age=a; /在此處只對派生類新增的數據成員初始化 void show( ) /輸出num,name和age display(); /輸出num和namecoutage: ageendl; private: /派生類的私有數據 int age; /增加一個數據成員;class Student2:public Student1 /聲明間接公用派生類student2 public: /下面是間接派生類構造函數 Student2(int n,string nam,int a,int s):Student1(n,nam,a) score=s; void sh

24、ow_all() /輸出全部數據成員 show(); /輸出num和name coutscore:scoreendl;/輸出age private: int score;/增加一個數據成員; int main( )Student2 stud(10010,Li,17,89);stud.show_all( ); /輸出學生的全部數據return 0;num:10010name:Liage: 17score:89圖11.1311.5.4派生類構造函數的特殊形式11.5.5派生類的析構函數析構函數的執(zhí)行順序與構造函數正好相反:先執(zhí)行派生類的析構函數,再執(zhí)行子對象的析構函數,最后執(zhí)行基類的析構函數。/測

25、試例子#includeclass base private: int a;public: base(int i); base(); base : base(int i)a=i;cout constructing base aendl;base : base()cout destroying base aendl;class derived : public base private: int d; base member;public: derived(int i,int j,int k); derived();derived : derived(int i,int j,int k):base

26、(i),member(j)d=k;cout constructing derivedendl;derived : derived()cout destroying derivedendl;void main()derived d(5,8,12);constructing base 5constructing base 8constructing deriveddestroying deriveddestroying base 8destroying base 511.6多重繼承11.6.1聲明多重繼承的方法class D:public A,private B,protected C類D新增加的

27、成員11.6.2多重繼承派生類的構造函數派生類構造函數(總參數表列):基類1構造函數名(參數表列),基類2構造函數(參數表列),基類3構造函數(參數表列)派生類中新增數據成員初始化語句例11.8 聲明一個教師(Teacher)類和一個學生(Student)類,用多重繼承方式聲明一個研究生(Graduate)派生類。教師類包括數據成員name,age,title.學生類中包括數據成員name1,sex,score.在定義派生類對象時給出初始化數據,然后輸出這些數據。#include #include using namespace std;class Teacher /聲明Teacher(教師)

28、類public: /公用部分Teacher(string nam,int a,string t) name=nam;age=a;title=t;/構造函數 void display()/輸出教師有關數據 coutname:nameendl;coutageageendl;couttitle:titleendl; protected: /保護部分 string name; int age; string title; /職稱;class Student /聲明類Student(學生)public:Student(string nam,char s,float sco) name1=nam;sex=

29、s;score=sco;/構造函數void display1() /輸出學生有關數據 coutname:name1endl;coutsex:sexendl;coutscore:scoreendl; protected: /保護部分string name1;char sex;float score; /成績;class Graduate:public Teacher,public Student public:/聲明多重繼承的派生類GraduateGraduate(string nam,int a,char s,string t,float sco,float w): Teacher(nam,a

30、,t),Student(nam,s,sco),wage(w)void show( ) /輸出人員的有關數據 coutname:nameendl;coutage:ageendl;coutsex:sexendl;coutscore:scoreendl;couttitle:titleendl;coutwages:wageendl; private: float wage; /工資;int main( )Graduate grad1(Wang-li,24,f,assistant, 89.5,1234.5);grad1.show( );return 0;name:Wang-liage:24sex:fsc

31、ore:89.5title:assistantwages:1234.5#includeclass base1public:base1()cout constructing baselendl;class base2public:base2()cout constructing base2endl;class base3public:base3()coutconstructing base3endl;class base4public:base4()coutconstructing base4endl;class derived : public base2,public base1,publi

32、c base3private:base4 memobj;void main()derived d;constructing base2constructing baselconstructing base3constructing base411.6.3多重繼承引起的二義性問題(1) 兩個基類有同名成員。class Apublic:int a:void display();class Bpublic:int a:void display();class C:public A,public Bpublic:int b:void show();圖11.14C c1;c1.a=3;產生二義性,應改為

33、 c1.A:a=3;使用基類名來限定c1.display();產生二義性,應改為c1.B:display();在C類成員函數中可以這么寫:A:a=3;B:a=8; B:display();圖11.15(2) 兩個基類和派生類都有同名成員,將上面C類改為:class C:public A,public Bpublic:int a;void display();C c1;c1.a=3;/正確,派生類同名成員覆蓋了基類中同名成員。c1.display();/正確。此時強制使用基類名的辦法是;c1.A:a=3;/使用基類名來限定c1.B:display();/使用基類名來限定(3)如果類A和類B是從同

34、一個基類派生的。class Npublic:int a;void display()coutA:a=aendl;class A:public Npublic:int a1:class B:public Npublic:int a2:class C:public A,public Bpublic:int a3:void show()couta3=a3endl;void main()C c1; 圖11.19 圖11. 20怎樣才能訪問類A中從基類N繼承下來的成員呢?不能寫成c1.a=3;c1.dispay();或c1.N:a=3;c1.N:display();應該寫成:c1.A:a=3;c1.B:

35、display();11.6.4虛基類1. 虛基類的作用 圖11.21圖11.22現將類A聲明為虛基類:class A.;class B:virtual public A.;class C:virtual public A.;class D:public B,public C.;則此時,D只繼承基類A一次。 圖11.24圖11.23注意:為了保證虛基類在派生類中只繼承一次,應當在該基類的所有直接派生類中聲明為虛基類。2. 虛基類的初始化class AA(int i).;class B:virtual public AB(int n):A(n).;class C:virtual public A

36、C(int n):A(n).;class D:public B,public CD(int n):A(n),B(n),C(n).;注意:在定義類D的構造函數時,與以往使用的方法有所不同。以前,在派生類的構造函數中只負責對其直接基類的初始化,再由其直接基類負責對間接基類初始化。現在,由于虛基類在派生類中只有一份數據成員,所以這份數據成員的初始化,必須由派生類直接給出。3. 虛基類的簡單應用舉例 圖11.25例11.9 在例11.8的基礎上,在Teacher類和Student類之上增加一個共同的基類Person,作為人員的一些基本數據都放在Person中,在Teacher類和Student類中增加

37、一些必要數據。#include #include using namespace std;/定義公共基類Personclass Person public:Person(char *nam,char s,int a) /構造函數 strcpy(name,nam);sex=s;age=a;protected: /保護成員char name20;char sex;int age;/定義類Teacherclass Teacher:virtual public Personpublic: /聲明Person為公用繼承的虛基類 Teacher(char *nam,char s,int a, char *

38、t):Person(nam,s,a) strcpy(title,t); /構造函數protected: /保護成員 char title10;/職稱;/定義類Studentclass Student:virtual public Person public: /聲明Person為公用繼承的虛基類Student(char *nam,char s,int a,float sco): Person(nam,s,a),score(sco)/構造函數初始化表protected: /保護成員 float score; /成績;/定義多重繼承的派生類Graduateclass Graduate:public

39、 Teacher,public Studentpublic:/聲明Teacher和Student類為公用繼承的直接基類Graduate(char *nam,char s,int a,char *t, float sco,float w): /構造函數 Person(nam,s,a),Teacher(nam,s,a,t), Student(nam,s,a,sco),wage(w) /初始化表 void show( ) /輸出研究生的有關數據 coutname:nameendl;coutage:ageendl;coutsex:sexendl;coutscore:scoreendl;couttitl

40、e:titleendl;coutwages:wageendl; private: float wage; /工資;int main( )Graduate grad1(Wang-li,f, 24,assistant,89.5,1234.5);grad1.show( );return 0;name:Wang-liage:24sex:fscore:89.5title:assistantwages:1234.511.7基類與派生類的轉換(1) 派生類對象可以向基類對象賦值。A a1;/定義基類A的對象a1B b1;/定義類A的公用派生類B的對象b1a1=b1;/用派生類B的對象b1對基類對象a1賦值但

41、是,反過來不成立,基類對象不能向派生類對象賦值,因為基類不包含派生類新增數據成員。圖11.26(2)派生類對象可以替代基類對象向基類對象的引用進行賦值或初始化。A a1;/定義基類A的對象a1B b1;/定義類A的公用派生類B的對象b1A&r=b1;/定義基類A對象的引用變量r,并用 /派生類B的對象b1對其進行初始化注意:此時r并不是b1的別名,也不與b1共享同一段存儲單元。它只是b1中基類部分的別名,r與b1中基類部分共享同一段存儲單元,r與b1具有相同的起始地址。(3)如果函數的參數是基類對象或基類對象的引用,相應的實參可以用派生類的對象。void fun(A& r)coutr.nume

42、ndl;fun(b1);(4)派生類對象的地址可以賦值指向基類對象的指針變量。例11.10 定義一個基類Student(學生),再定義Student類的公用派生類Graduate(研究生),用指向基類的對象的指針輸出數據。#include #include using namespace std;class Studentpublic: Student(int,string,float); void display();private: int num; string name; float score;Student:Student(int n,string nam,float s)num=n;name=nam;score=s;void Student:display()coutendlnum:numendl;coutname:nameendl;coutscore:scoreendl;class Graduate:publi

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論