版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第六章第六章 派生類和繼承派生類和繼承6.1、派生類的概念、派生類的概念6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)6.3、多重繼承、多重繼承C+的精華的精華6.1、派生類的概念、派生類的概念1、派生類的概念、派生類的概念2、為什么使用派生類、為什么使用派生類3、派生類的聲明方法、派生類的聲明方法4、私有派生的特性、私有派生的特性5、公有派生的特性、公有派生的特性6、保護成員在公、私派生中的特性、保護成員在公、私派生中的特性6.1、派生類的概念、派生類的概念1、派生類、派生類C+中使用繼承性進行代碼重用的方式就是中使用繼承性進行代碼重用的方式就是派生派生繼承繼承是面向?qū)ο蟪绦?/p>
2、設(shè)計支持是面向?qū)ο蟪绦蛟O(shè)計支持代碼重用代碼重用的重要機制的重要機制汽車客車貨車運輸汽車消防車灑水車專有汽車派生類在原有類的基礎(chǔ)上創(chuàng)建新的類派生類在原有類的基礎(chǔ)上創(chuàng)建新的類:(1)獲得一個或多個獲得一個或多個原有類中的函數(shù)和數(shù)據(jù);原有類中的函數(shù)和數(shù)據(jù);(2) 可以可以重新定義重新定義和和增加增加新的屬性和方法新的屬性和方法從而形成層次或等級關(guān)系從而形成層次或等級關(guān)系也便于對類進行組織也便于對類進行組織基類或者父類派生類或者子類6.1、派生類的概念、派生類的概念2、為什么使用派生類、為什么使用派生類class person private: char name10; int age; char s
3、ex; public: person(); void print();class employee private: char name10; int age; char sex; char department20; float salary; public: employee(); void print();employee類類與與person相比相比只是增加兩個屬性,其它相同只是增加兩個屬性,其它相同6.1、派生類的概念、派生類的概念3、 派生類的聲明方法派生類的聲明方法class 派生類名派生類名:派生方式派生方式 基類名基類名 /派生類中新的數(shù)據(jù)成員和成員函數(shù)派生類中新的數(shù)據(jù)成員和成
4、員函數(shù) ;派生派生方式分為:方式分為:公有派生、私有派生、保護派生公有派生、私有派生、保護派生(1)基類成員到了派生類中后,訪問權(quán)限是什么?基類成員到了派生類中后,訪問權(quán)限是什么?(2) 對于這些基類成員,派生類的新成員能否訪問?對于這些基類成員,派生類的新成員能否訪問?public、private、protected帶來兩個問題:帶來兩個問題:6.1、派生類的概念、派生類的概念(1)公有派生中,基類中的公有成員在派生類是公有的,私有公有派生中,基類中的公有成員在派生類是公有的,私有成員在派生類是私有的成員在派生類是私有的(2) 私有派生中,基類中的私有派生中,基類中的所有成員所有成員在派生類
5、中是私有成員在派生類中是私有成員基類成員的訪問權(quán)限基類成員的訪問權(quán)限6.1、派生類的概念、派生類的概念基類基類公有公有成員成員基類基類私有私有成員成員基類基類派生派生類類基類基類公有公有成員成員基類基類私有私有成員成員新新公有公有成員成員新新私有私有成員成員公有派生公有派生基類基類公有公有成員成員基類基類私有私有成員成員基類基類派生派生類類基類基類私有私有成員成員基類基類私有私有成員成員新新公有公有成員成員新新私有私有成員成員私有派生私有派生分析:派生類新舊成員之間的訪問權(quán)限如何?分析:派生類新舊成員之間的訪問權(quán)限如何?6.1、派生類的概念、派生類的概念4、私有私有派生的特性派生的特性(1)私
6、有派生對基類成員的訪問私有派生對基類成員的訪問 基類所有的公有成員基類所有的公有成員都成為派生類的私有成員,他們能夠都成為派生類的私有成員,他們能夠被派生類的成員訪問;被派生類的成員訪問; 基類所有的私有成員基類所有的私有成員不能被派生類成員訪問,但可以通過不能被派生類成員訪問,但可以通過基類的公有成員函數(shù)訪問基類的公有成員函數(shù)訪問(2)外部函數(shù)對私有派生類、繼承類的成員的訪問外部函數(shù)對私有派生類、繼承類的成員的訪問 基類中的所有成員在派生類中都成為私有成員,外部函數(shù)基類中的所有成員在派生類中都成為私有成員,外部函數(shù)不能夠訪問不能夠訪問到了派生類中的成員到了派生類中的成員6.1、派生類的概念、
7、派生類的概念舉例舉例#include class base /定義基類定義基類 int x; public: void setx(int n) x=n; void showx() cout xendl; ;class derived : private base /定義私有派生類定義私有派生類 int y; public: void setxy(int n, int m) /設(shè)定類的屬性的值設(shè)定類的屬性的值 setx(n); /調(diào)用基類函數(shù)調(diào)用基類函數(shù) y=m; 合法:合法:setx可被可被setxy訪問訪問6.1、派生類的概念、派生類的概念 void showxy() coutxyendl;
8、 /非法非法,不能訪問,不能訪問x;main() derived obj; obj.setx(10); /非法非法,外部不能對私有派生繼承來的成員訪問,外部不能對私有派生繼承來的成員訪問 obj.setxy(10,20); /合法合法 obj.showx(); /非法非法,外部不能對私有派生繼承來的成員訪問外部不能對私有派生繼承來的成員訪問 obj.showxy(); /合法合法 return 0;6.1、派生類的概念、派生類的概念5、公有公有派生的特性派生的特性公有派生時基類成員的可訪問性在派生類中維持不變:公有派生時基類成員的可訪問性在派生類中維持不變: 基類中的私有成員基類中的私有成員在
9、派生類仍是私有成員,不允許外部函數(shù)在派生類仍是私有成員,不允許外部函數(shù)和派生類的成員函數(shù)訪問;和派生類的成員函數(shù)訪問; 基類中的公有成員基類中的公有成員仍是派生類中的公有成員,外部函數(shù)和派仍是派生類中的公有成員,外部函數(shù)和派生類的成員可以直接訪問生類的成員可以直接訪問6.1、派生類的概念、派生類的概念舉例舉例#includeclass base /定義基類定義基類 int x;public: void setx(int n) x=n; void showx() cout xendl; ;class derived : public base /定義公有派生類定義公有派生類 int y;publ
10、ic: void sety(int n) y=n; void showy() coutyendl; / void showxy() coutxendl; coutyendl; ;非法非法6.1、派生類的概念、派生類的概念main() derived obj; obj.setx(10); /合法合法 obj.sety(20); /合法合法 obj.showx(); /合法合法 obj.showy(); /合法合法 return 0;6.1、派生類的概念、派生類的概念6、保護成員保護成員在公、私派生中的特性在公、私派生中的特性保護成員可以被派生類中的成員函數(shù)訪問,但是對于保護成員可以被派生類中的成
11、員函數(shù)訪問,但是對于外界是掩藏的外界是掩藏的(1)私有派生中:私有派生中: 基類的保護成員基類的保護成員成為派生類的私有成員,他們能夠被派生成為派生類的私有成員,他們能夠被派生類的成員訪問,不能被外部函數(shù)訪問;類的成員訪問,不能被外部函數(shù)訪問;(2)公有派生中:公有派生中: 基類的保護成員基類的保護成員成為派生類的保護成員,他們能夠被派生成為派生類的保護成員,他們能夠被派生類的成員訪問,不能被外部函數(shù)訪問;類的成員訪問,不能被外部函數(shù)訪問;訪問性質(zhì)在兩種派生中一樣訪問性質(zhì)在兩種派生中一樣原則:原則:對派生類相當(dāng)于公有,對外部函數(shù)相當(dāng)于私有對派生類相當(dāng)于公有,對外部函數(shù)相當(dāng)于私有6.1、派生類的
12、概念、派生類的概念舉例舉例#includeclass base /定義類定義類base protected: /定義保護成員定義保護成員 int a, b; public: void setab(int n,int m) /設(shè)定屬性的值設(shè)定屬性的值 a=n; b=m; ;class derived : public base /定義公有派生類定義公有派生類derive int c; public: void setc(int n) c=n; void showbc() cout b cendl; /允許訪問派生類的成員允許訪問派生類的成員b;private6.1、派生類的概念、派生類的概念ma
13、in() /主函數(shù)主函數(shù) derived obj; /定義對象定義對象obj obj.setab(2,4); /設(shè)定基類保護成員的值設(shè)定基類保護成員的值 obj.setc(3); obj.showbc(); /顯示對象的值顯示對象的值 obj.b=3;/非法非法 return 0; 一般來說一般來說,將基類私有成員中需要提供給派生類訪問,將基類私有成員中需要提供給派生類訪問的成員定義為保護成員的成員定義為保護成員6.1、派生類的概念、派生類的概念總結(jié):總結(jié):繼承方式繼承方式publicpublic派生派生protectedprotected派生派生privateprivate派生派生publi
14、cpublic基類成員基類成員訪問屬性訪問屬性 派生類成員派生類成員訪問屬性訪問屬性publicpublicprotectedprotectedprivateprivateprotectedprotectedprivateprivate在派生類中隱藏在派生類中隱藏protectedprotectedprotectedprotectedprivateprivate在派生類中隱藏在派生類中隱藏privateprivateprivateprivateprivateprivate在派生類中隱藏在派生類中隱藏基類的成員可以訪問,基類的成員可以訪問,因此通過基類的公有成員間接訪問因此通過基類的公有成員間接
15、訪問(1)訪問權(quán)限:訪問權(quán)限:如果不顯示指定繼承方式,編譯如果不顯示指定繼承方式,編譯器默認為私有繼承器默認為私有繼承6.1、派生類的概念、派生類的概念(2)派生類除擁有基類成員外:派生類除擁有基類成員外:(a)可以可以增加增加新的數(shù)據(jù)成員和成員函數(shù)。新的數(shù)據(jù)成員和成員函數(shù)。(b)可以可以重新定義重新定義基類的成員函數(shù)。基類的成員函數(shù)。(c)可以可以修改修改現(xiàn)有成員的屬性?,F(xiàn)有成員的屬性。6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)1、研究派生類構(gòu)造、析構(gòu)函數(shù)的原因、研究派生類構(gòu)造、析構(gòu)函數(shù)的原因 因為派生類繼承了基類的成員,所以在實例化派生因為派生類繼承了基類的成員,所以在實
16、例化派生類對象時,必須調(diào)用基類的構(gòu)造函數(shù)來初始化派生類對類對象時,必須調(diào)用基類的構(gòu)造函數(shù)來初始化派生類對象中基類的成員象中基類的成員 當(dāng)然也要調(diào)用派生類的構(gòu)造函數(shù)當(dāng)然也要調(diào)用派生類的構(gòu)造函數(shù)需要研究兩者的需要研究兩者的如何調(diào)用、調(diào)用次序、參數(shù)傳遞如何調(diào)用、調(diào)用次序、參數(shù)傳遞關(guān)系等關(guān)系等 派生類既可以派生類既可以隱式隱式調(diào)用基類的構(gòu)造函數(shù),也可以在調(diào)用基類的構(gòu)造函數(shù),也可以在派生類的構(gòu)造函數(shù)中派生類的構(gòu)造函數(shù)中顯式顯式的調(diào)用基類的構(gòu)造函數(shù)的調(diào)用基類的構(gòu)造函數(shù)6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)2、派生類構(gòu)造函數(shù)和析構(gòu)函數(shù)執(zhí)行、派生類構(gòu)造函數(shù)和析構(gòu)函數(shù)執(zhí)行順序順序創(chuàng)建派生類
17、對象創(chuàng)建派生類對象: (1)執(zhí)行基類的構(gòu)造函數(shù)執(zhí)行基類的構(gòu)造函數(shù) (2)執(zhí)行派生類的構(gòu)造函數(shù)執(zhí)行派生類的構(gòu)造函數(shù)撤銷派生類對象撤銷派生類對象: 執(zhí)行派生類的析構(gòu)函數(shù)執(zhí)行派生類的析構(gòu)函數(shù) 執(zhí)行基類的析構(gòu)函數(shù)執(zhí)行基類的析構(gòu)函數(shù)6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)3、派生類構(gòu)造函數(shù)和析構(gòu)函數(shù)的、派生類構(gòu)造函數(shù)和析構(gòu)函數(shù)的構(gòu)造規(guī)則構(gòu)造規(guī)則(1)基類的構(gòu)造函數(shù)基類的構(gòu)造函數(shù)沒有參數(shù)沒有參數(shù),或者,或者沒有顯式地定義構(gòu)造函數(shù)沒有顯式地定義構(gòu)造函數(shù)的的時候,派生類可以不向基類傳遞參數(shù),甚至可以不定義構(gòu)造函數(shù)時候,派生類可以不向基類傳遞參數(shù),甚至可以不定義構(gòu)造函數(shù)(2)派生類派生類不能
18、繼承不能繼承基類中的構(gòu)造函數(shù)和析構(gòu)函數(shù)?;愔械臉?gòu)造函數(shù)和析構(gòu)函數(shù)。當(dāng)基類中當(dāng)基類中帶有參數(shù)的構(gòu)造函數(shù)帶有參數(shù)的構(gòu)造函數(shù)的時候,派生類必須定義構(gòu)造函數(shù),的時候,派生類必須定義構(gòu)造函數(shù),且且顯式調(diào)用顯式調(diào)用派生類中構(gòu)造函數(shù)的格式:派生類中構(gòu)造函數(shù)的格式:派生類構(gòu)造函數(shù)名(參數(shù)表派生類構(gòu)造函數(shù)名(參數(shù)表):基類構(gòu)造函數(shù)名(參數(shù)表)基類構(gòu)造函數(shù)名(參數(shù)表) /對新成員的構(gòu)造對新成員的構(gòu)造 顯式調(diào)用顯式調(diào)用基類的構(gòu)造函數(shù)基類的構(gòu)造函數(shù)去掉則為去掉則為隱式調(diào)用隱式調(diào)用必須顯式或隱式調(diào)用必須顯式或隱式調(diào)用6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)舉例舉例/point.h文件,文件,Poi
19、nt類的聲明類的聲明#include #ifndef POINT_H#define POINT_Hclass Point /聲明聲明Point類類 public:Point( int = 0,int = 0); /Point的構(gòu)造函數(shù)的構(gòu)造函數(shù)Point(); /Point的析構(gòu)函數(shù)的析構(gòu)函數(shù) protected:int x,y;6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)/定義定義Point類的成員函數(shù)類的成員函數(shù)Point:Point(int a,int b) /定義定義Point類的構(gòu)造函數(shù)類的構(gòu)造函數(shù)x=a;y=b;coutPoint constructor:x,yen
20、dl;Point:Point() /定義定義Point類的析構(gòu)函數(shù)類的析構(gòu)函數(shù)coutPoint destructor:x,yendl;#endif6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)/circle.h文件,文件,Circle類的聲明類的聲明#ifndef CIRCLE_H#define CIRCLE_H#include “point.h”class Circle:public Point /聲明聲明Circle類繼承自類類繼承自類Point public:Circle(double r=0.0,int x=0,int y=0); /Circle類類 /的構(gòu)造函數(shù)的構(gòu)造
21、函數(shù)Circle(); /Circle類的析構(gòu)函數(shù)類的析構(gòu)函數(shù) private:double radius;6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)/ 定義定義Circle類的成員函數(shù)類的成員函數(shù)Circle:Circle(double r,int a,int b):Point(a,b)radius = r;coutCircle constructor:radius is radiusx,yendl;Circle:Circle()coutCircle destructor:radius is radiusx,yendl;#endif 6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類
22、的構(gòu)造函數(shù)和析構(gòu)函數(shù)/try.cpp文件文件#include “point.h”#include “circle.h”int main()/演示演示Point類構(gòu)造函數(shù)和類構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用析構(gòu)函數(shù)的調(diào)用 Point p(11,22); coutendl;Circle circle1(4.5,72,29);coutendl;Circle circle2(10,5,5);coutendl;return 0;Circle destructor:radius is 10 5,5Point destructor:5,5Circle destructor:radius is 4.5 72,29Po
23、int destructor:72,29程序輸出結(jié)果程序輸出結(jié)果:Point Constructor:11,22Point destructor:11,22Point Constructor:72,29Circle constructor:radius is 4.5 72,29Point Constructor:5,5Circle constructor:radius is 10 5,56.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)#define POINT_H class Point /聲明聲明Point類類#define CIRCLE_H#define POINT_H cla
24、ss Point /聲明聲明Point類類class Circle:public Point /聲明聲明Circle類繼承自類類繼承自類Pointint main()6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)該例中定義了該例中定義了Point類和它的公有派生類類和它的公有派生類Circle。(1)在定義在定義Circle類的成員函數(shù)時,顯示調(diào)用類的成員函數(shù)時,顯示調(diào)用Point類類的構(gòu)造函數(shù)來對的構(gòu)造函數(shù)來對Cirle類中的基類成員初始化類中的基類成員初始化。(2)在在main()函數(shù)中,先實例化了一個函數(shù)中,先實例化了一個Point對象,對象,由于該對象在進入其作用域后又立
25、即退出其作用域,由于該對象在進入其作用域后又立即退出其作用域,因此調(diào)用了因此調(diào)用了Point的構(gòu)造函數(shù)和析構(gòu)函數(shù)的構(gòu)造函數(shù)和析構(gòu)函數(shù)(3)實例化實例化Cirlcle的對象的對象circle1時,時,首先調(diào)用了首先調(diào)用了Point的構(gòu)造函數(shù),然后再調(diào)用的構(gòu)造函數(shù),然后再調(diào)用Circle的構(gòu)造函數(shù)。接的構(gòu)造函數(shù)。接著,程序以同樣的順序?qū)嵗酥?,程序以同樣的順序?qū)嵗薱ircle2對象。對象。6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)在在main函數(shù)結(jié)束時,程序為函數(shù)結(jié)束時,程序為circle1和和circle2調(diào)用析構(gòu)函數(shù),因為析構(gòu)函數(shù)的調(diào)用順序和構(gòu)造調(diào)用析構(gòu)函數(shù),因為析構(gòu)函
26、數(shù)的調(diào)用順序和構(gòu)造函數(shù)相反,因此先為對象函數(shù)相反,因此先為對象circle2調(diào)用析構(gòu)函數(shù),調(diào)用析構(gòu)函數(shù),調(diào)用順序是先調(diào)用類調(diào)用順序是先調(diào)用類Circle的析構(gòu)函數(shù)的析構(gòu)函數(shù),再調(diào)用類再調(diào)用類Point的析構(gòu)函數(shù)。為對象的析構(gòu)函數(shù)。為對象circle2調(diào)用析構(gòu)函數(shù)完調(diào)用析構(gòu)函數(shù)完成后,再以相同的順序為對象成后,再以相同的順序為對象circle1調(diào)用析構(gòu)函調(diào)用析構(gòu)函數(shù)。數(shù)。6.3、多重繼承、多重繼承1、定義、語法、定義、語法定義定義:多重繼承是派生類有多個基類的派生方法:多重繼承是派生類有多個基類的派生方法語法語法:class 派生類名派生類名:派生方式派生方式1 基類名基類名1, , 派生方式派
27、生方式n 基類名基類名n /派生類新增的數(shù)據(jù)成員和成員函數(shù)派生類新增的數(shù)據(jù)成員和成員函數(shù);派生方式派生方式可以各不相同可以各不相同6.3、多重繼承、多重繼承2、訪問權(quán)限、構(gòu)造和析構(gòu)次序、訪問權(quán)限、構(gòu)造和析構(gòu)次序在多重繼承中,公有派生和私有派生對于基類成員在派在多重繼承中,公有派生和私有派生對于基類成員在派生類中的可訪問性和單繼承的生類中的可訪問性和單繼承的規(guī)則相同規(guī)則相同基類基類基類基類派生類派生類基類基類成員成員基類基類成員成員新成員新成員派生派生派生派生6.3、多重繼承、多重繼承構(gòu)造和析構(gòu)次序:構(gòu)造和析構(gòu)次序:在多重繼承中,多重繼承構(gòu)造函數(shù)的執(zhí)行順序與單繼承在多重繼承中,多重繼承構(gòu)造函數(shù)的
28、執(zhí)行順序與單繼承構(gòu)造函數(shù)的執(zhí)行順序相同,遵循先執(zhí)行構(gòu)造函數(shù)的執(zhí)行順序相同,遵循先執(zhí)行基類的構(gòu)造函數(shù)基類的構(gòu)造函數(shù),再執(zhí)行再執(zhí)行對象成員的構(gòu)造函數(shù)對象成員的構(gòu)造函數(shù),最后執(zhí)行,最后執(zhí)行派生類的構(gòu)造函派生類的構(gòu)造函數(shù)數(shù)的原則。的原則。6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)舉例:舉例:#include class X /聲明基類聲明基類int a;public:X(int sa) a=sa;int getX() return a;class Y /聲明另外的基類聲明另外的基類int b;public:Y(int sb) b=sb;int getY() return b;6.2、
29、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)class Z : public X, private Y /聲明派生類,多重繼承聲明派生類,多重繼承int c;public:Z(int sa,int sb,int sc):X(sa),Y(sb) /Z的的構(gòu)造函數(shù)構(gòu)造函數(shù) c=sc; /并并調(diào)用基類構(gòu)造函數(shù)調(diào)用基類構(gòu)造函數(shù)int getZ() return c;int getY() return Y:getY(); /重新定義繼承來的函數(shù)重新定義繼承來的函數(shù);main() /主函數(shù)主函數(shù)Z obj(2,4,6); /聲明對象聲明對象objint ma=obj.getX(); /調(diào)用基類調(diào)用
30、基類X的方法的方法cout“a=”maendl;cout“b=”obj.getY()endl; return 0;return c+1;6.3、多重繼承、多重繼承XYZa getX派生派生派生派生b getYc getZ6.3、多重繼承、多重繼承3、繼承的模糊性(繼承歧義性)繼承的模糊性(繼承歧義性) #include class Veichle /定義交通工具類定義交通工具類 public:Veichle(double w = 0)cout“Veichle constructor”endl; weight = w; void setWeight(double w) cout“set weig
31、ht:”endl; weight = w; protected:double weight; ;6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)class Veichle_Road: public Veichle /定義陸地交通工具類定義陸地交通工具類public:Veichle_Road(double weitht=0,int s=0): Veichle(weight)cout Veichle_Road constructorendl; speed = s; protected:int speed;6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)class Veich
32、le_Water:public Veichle /定義水上交通工具類定義水上交通工具類public:Veichle_Water(double weight=0,float t=0): Veichle(weight) cout Veichle_Water constructorendl;tonnage = t; protected:float tonnage;6.2、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)class Amphicar : public Veichle_Road, public Veichle_Waterpublic:/多重繼承,調(diào)用基類構(gòu)造函數(shù)多重繼承,調(diào)用基類構(gòu)造
33、函數(shù) Amphicar(double w, int s, float t) : Veichle_Road(w,s), Veichle_Water(w,t) /正確正確, 分別初始化兩個分別初始化兩個wcout “ Amphicar constructor”endl; void display( ) /顯示顯示Amphicar成員成員cout“ weight: ” weight“ ,” endl; /錯誤錯誤,因為多繼承帶來的歧義性因為多繼承帶來的歧義性 cout speed:speedendl;cout tonnage: tonnageendl; ;顯示哪個顯示哪個w?6.2、派生類的構(gòu)造函數(shù)
34、和析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)void main( )Amphicar a(4.0,200,1.50f); /正確正確 a.setWeight(3.5); /錯誤錯誤, 因為多繼承帶來的歧義性因為多繼承帶來的歧義性 a.display( );原因原因: a從從Veichle_Road和和Veichle_Water繼承了繼承了w、setWeight()的()的兩個兩個拷貝拷貝解決解決: 采用虛擬繼承!采用虛擬繼承!此外此外: 從不同類繼承同名成員,也會出現(xiàn)從不同類繼承同名成員,也會出現(xiàn)歧義性歧義性6.3、多重繼承、多重繼承4、虛擬繼承虛擬繼承目的目的:如果要使公共基類只產(chǎn)生一個拷貝,則應(yīng)當(dāng)
35、把:如果要使公共基類只產(chǎn)生一個拷貝,則應(yīng)當(dāng)把這個基類聲明為虛基類。這個基類聲明為虛基類。 即:要求從基類派生新類時,使用即:要求從基類派生新類時,使用關(guān)鍵字關(guān)鍵字virtual將基類聲明為虛基類。將基類聲明為虛基類。語法語法:class 派生類名派生類名:virtual 派生派生方式方式 基類名基類名;虛基類虛基類6.3、多重繼承、多重繼承修改上例:修改上例:#include class Veichle /定義交通工具類定義交通工具類public:Veichle(double w = 0)coutVeichle constructorendl; weight = w; void setWeig
36、ht(double w) coutset weight=wendl;weight = w; protected:double weight; ;6.3、多重繼承、多重繼承class Veichle_Road: virtual public Veichle /虛繼承虛繼承public:Veichle_Road(double weitht=0,int s=0): Veichle(weight) cout Veichle_Road constructorendl; speed = s; protected:int speed;6.3、多重繼承、多重繼承class Veichle_Water:virt
37、ual public Veichle /水上交通工具水上交通工具,這里是這里是 /虛擬繼承虛擬繼承 public:Veichle_Water(double weight=0,float t=0): Veichle(weight) cout Veichle_Water constructorendl;tonnage = t; protected:float tonnage;6.3、多重繼承、多重繼承class Amphicar :public Veichle_Road, public Veichle_Water /多繼承多繼承 public: Amphicar(double w, int s,
38、float t):Veichle(w), Veichle_Road(w,s), Veichle_Water(w,t) cout Amphicar constructorendl; void display( ) /顯示顯示Amphicar的的Weight成員成員coutAmphicar object contains: endl;cout weight: weightendl;cout speed:speedendl; cout tonnage: tonnageendl; ;6.3、多重繼承、多重繼承void main( )Amphicar amp(4.0,200,1.50f);amp.set
39、Weight(2.0); /調(diào)用調(diào)用Veichel的的setWeight成員成員amp.display();6.3、多重繼承、多重繼承程序輸出結(jié)果程序輸出結(jié)果:Veichle constructorVeichle_Road constructorVeichle_Water constructor(此處不調(diào)用此處不調(diào)用Veichle構(gòu)造該函數(shù)構(gòu)造該函數(shù)) Amphicar constructorset weight=2Amphicar object contains: weight: 2speed:200tonnage:1.56.3、多重繼承、多重繼承分析:分析:從類從類Veichle派生出類派
40、生出類Veichle_Road和類和類Veichle_Water時,使用了關(guān)鍵字時,使用了關(guān)鍵字virtual實現(xiàn)虛擬實現(xiàn)虛擬繼承繼承。則對于虛基類則對于虛基類Veichle ,編譯器編譯器遇到多重繼承時會遇到多重繼承時會自自動動加上一個拷貝,當(dāng)加上一個拷貝,當(dāng)再次請求再次請求一個一個Veichle拷貝時就拷貝時就會會被忽略被忽略,保證繼承成員的唯一性。,保證繼承成員的唯一性。6.3、多重繼承、多重繼承類類Amphicar只有一個只有一個Veichle類的拷貝,從類的拷貝,從而既可以消除歧義性,而既可以消除歧義性,又可以正確的描述類又可以正確的描述類層次結(jié)構(gòu)層次結(jié)構(gòu)一個一個Amphicar對象
41、在內(nèi)存中的布局如下圖對象在內(nèi)存中的布局如下圖: 不能將不能將virtual寫在寫在Amphicar 的定義處的定義處6.3、多重繼承、多重繼承weightVeichlesetWeightweightVeichlesetWeightspeedweightsetWeighttonnageweightsetWeightspeedweightsetWeighttonnageweightsetWeightspeedweightsetWeightVeichle_RoadtonnageweightsetWeightVeichle_WaterspeedweightsetWeighttonnageweights
42、etWeightAmphicar6.3、多重繼承、多重繼承使用使用虛擬繼承機制的注意事項:虛擬繼承機制的注意事項:1、如果在虛基類中定義了帶參數(shù)的構(gòu)造函數(shù),在整個繼承結(jié)如果在虛基類中定義了帶參數(shù)的構(gòu)造函數(shù),在整個繼承結(jié)構(gòu)中,所有的直接或間接派生類中都必須在構(gòu)造函數(shù)中使用構(gòu)中,所有的直接或間接派生類中都必須在構(gòu)造函數(shù)中使用成員初始化列表的方式調(diào)用虛基類的構(gòu)造函數(shù),初始化虛基成員初始化列表的方式調(diào)用虛基類的構(gòu)造函數(shù),初始化虛基類中的成員類中的成員2、如果在同一個繼承層次中同時包含虛基類和非虛基類,如果在同一個繼承層次中同時包含虛基類和非虛基類, C+編譯器先調(diào)用虛基類的構(gòu)造函數(shù),再調(diào)用非虛基類的構(gòu)
43、編譯器先調(diào)用虛基類的構(gòu)造函數(shù),再調(diào)用非虛基類的構(gòu)造函數(shù)造函數(shù)3、如果虛基類是由非虛基類派生而來,同樣遵守先調(diào)用基如果虛基類是由非虛基類派生而來,同樣遵守先調(diào)用基類構(gòu)造函數(shù)再調(diào)用派生類構(gòu)造函數(shù)的規(guī)則類構(gòu)造函數(shù)再調(diào)用派生類構(gòu)造函數(shù)的規(guī)則6.3、多重繼承、多重繼承慎用多重慎用多重繼承:繼承:盡管多重機制在一定程度上強化了對現(xiàn)實世界中盡管多重機制在一定程度上強化了對現(xiàn)實世界中事物的描述,但是在實際應(yīng)用中并不建議使用多事物的描述,但是在實際應(yīng)用中并不建議使用多重繼承,主要是因為編譯器的問題,還有多重繼重繼承,主要是因為編譯器的問題,還有多重繼承機制會帶來二義性問題。單繼承對描述事物已承機制會帶來二義性問
44、題。單繼承對描述事物已經(jīng)提供了足夠強大的功能,不一定非要使用多繼經(jīng)提供了足夠強大的功能,不一定非要使用多繼承不可承不可6.3、多重繼承、多重繼承引入引入虛擬繼承后,多重繼承中虛擬繼承后,多重繼承中構(gòu)造函數(shù)和析構(gòu)構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行函數(shù)的執(zhí)行順序順序 (對前面內(nèi)容的擴展)(對前面內(nèi)容的擴展)1、任何、任何虛擬繼承基類虛擬繼承基類的構(gòu)造函數(shù)按照它們被繼承的順序構(gòu)造的構(gòu)造函數(shù)按照它們被繼承的順序構(gòu)造2、任何任何非虛擬基類非虛擬基類的構(gòu)造函數(shù)按照它們被繼承的順序構(gòu)造的構(gòu)造函數(shù)按照它們被繼承的順序構(gòu)造3、派生類自己的構(gòu)造函數(shù)派生類自己的構(gòu)造函數(shù)析構(gòu)函數(shù)的執(zhí)行順序與構(gòu)造函數(shù)執(zhí)行的順序相反析構(gòu)函數(shù)的執(zhí)行
45、順序與構(gòu)造函數(shù)執(zhí)行的順序相反6.3、多重繼承、多重繼承/檢驗多重繼承構(gòu)造順序檢驗多重繼承構(gòu)造順序#include class Base1public:Base1( )coutBase1 construcotrendl;Base1( ) coutBase1deconstrucotrendl;class Base2public:Base2( ) coutBase2 construcotrendl; Base2() coutBase2 deconstrucotrendl;6.3、多重繼承、多重繼承class Base3public:Base3( ) coutBase3 construcotrendl
46、; Base3( ) coutBase3 deconstrucotrendl; ;class Base4public:Base4( ) coutBase4 construcotrendl;Base4( ) coutBase4 deconstrucotrendl;6.3、多重繼承、多重繼承class Member1public:Member1( ) coutMember1 construcotrendl; Member1( ) coutMember1 deconstrucotrendl;class Member2public:Member2( ) coutMember2 construcotre
47、ndl; Member2( ) coutMember2 deconstrucotrendl;6.3、多重繼承、多重繼承class Derived: public Base1,virtual public Base2, public Base3,virtual public Base4 public:Derived( ):Base1( ),Base2( ),Base3( ),Base4( ), mem1 ( ), mem2 ( ) cout Derived constructorendl; Derived( ) cout Derived constructorendl; ;private: Me
48、mber1 mem1; Member2 mem2;6.3、多重繼承、多重繼承int main( ) Derived obj;coutconstructor finish!endl;return 0;程序運行結(jié)果為程序運行結(jié)果為:Base2 construcotrBase4 construcotrBase1 construcotrBase3 construcotrMember1 construcotrMember2 construcotrDerived constructorconstructor finish! Derived deconstructorMember2 deconstrucot
49、rMember1 deconstrucotrBase3 deconstrucotrBase1 deconstrucotrBase4 deconstrucotrBase2 deconstrucotr 6.3、多重繼承、多重繼承輸出結(jié)果表明:輸出結(jié)果表明:Derived的虛基類的虛基類Base2和和Base4首先被構(gòu)造,首先被構(gòu)造,非虛基類非虛基類Base1和和Base3隨后被構(gòu)造,與它們在隨后被構(gòu)造,與它們在Derived的構(gòu)造函數(shù)中出現(xiàn)的次序無關(guān)。的構(gòu)造函數(shù)中出現(xiàn)的次序無關(guān)。然后然后Derived的成員對象的成員對象Mem1和和Mem2按照在按照在Derived中聲明的順序構(gòu)造,中聲明的順序構(gòu)
50、造,最后執(zhí)行最后執(zhí)行Derived的構(gòu)造函數(shù),構(gòu)造的構(gòu)造函數(shù),構(gòu)造Derived對象。對象。析構(gòu)函數(shù)的執(zhí)行順序與構(gòu)造函數(shù)相反析構(gòu)函數(shù)的執(zhí)行順序與構(gòu)造函數(shù)相反本章小結(jié)本章小結(jié)1、本章介紹了、本章介紹了C+中關(guān)于繼承機制的相關(guān)知識中關(guān)于繼承機制的相關(guān)知識,使使用繼承機制可以簡化對事物的描述用繼承機制可以簡化對事物的描述,同時更好的實現(xiàn)同時更好的實現(xiàn)軟件復(fù)用。繼承分為單繼承和多重繼承軟件復(fù)用。繼承分為單繼承和多重繼承,我們別按照我們別按照如何聲明派生類如何聲明派生類、 繼承的訪問控制繼承的訪問控制、 派生類的構(gòu)造派生類的構(gòu)造和析構(gòu)和析構(gòu)對兩種繼承機制進行了詳細的介紹對兩種繼承機制進行了詳細的介紹。2
51、、關(guān)于多繼承,我們重點介紹了、關(guān)于多繼承,我們重點介紹了多重繼承的模糊性多重繼承的模糊性,并引入了并引入了虛擬繼承虛擬繼承。在語言中實現(xiàn)多繼承并不容易,。在語言中實現(xiàn)多繼承并不容易,主要是編譯程序的問題和多重繼承可能會產(chǎn)生二義性,主要是編譯程序的問題和多重繼承可能會產(chǎn)生二義性,在實際開發(fā)中,應(yīng)避免使用多重繼承。在實際開發(fā)中,應(yīng)避免使用多重繼承。綜合訓(xùn)練綜合訓(xùn)練1題目題目:編寫程序列出某讀者的借書情況:編寫程序列出某讀者的借書情況: 假設(shè)圖書館的圖書包含假設(shè)圖書館的圖書包含書名、編號、作者屬性書名、編號、作者屬性。讀者包含讀者包含姓名姓名和和借書證編號屬性借書證編號屬性,每位讀者最多可借,每位讀者最多可借5本書,本書,綜合訓(xùn)練綜合訓(xùn)練1分析分析show()namenoshowbook()bookauthornamenoshowreader()reader對象數(shù)組:存放借書對象數(shù)組:存放借書showbook() show() 顯示作者顯示作者showreader() show() 顯示借書顯示借書 namenoshow()show()綜合訓(xùn)練綜合訓(xùn)練1#include #include class object char name2
溫馨提示
- 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)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版生物質(zhì)發(fā)電監(jiān)理服務(wù)合同三方協(xié)議3篇
- 二零二五版企業(yè)安全風(fēng)險評估與安保服務(wù)合同3篇
- 二零二五年度高品質(zhì)鋼結(jié)構(gòu)裝配式建筑安裝服務(wù)合同3篇
- 二零二五版電影投資融資代理合同樣本3篇
- 二零二五版初級農(nóng)產(chǎn)品電商平臺入駐合同2篇
- 二零二五年度電商平臺安全實驗報告安全防護方案合同3篇
- 二零二五年度白酒銷售區(qū)域保護與競業(yè)禁止合同3篇
- 二零二五版建筑工程專用防水材料招投標合同范本3篇
- 二零二五年研發(fā)合作與成果共享合同2篇
- 二零二五版鋼結(jié)構(gòu)工程節(jié)能合同范本下載3篇
- 2024年四川省德陽市中考道德與法治試卷(含答案逐題解析)
- 施工現(xiàn)場水電費協(xié)議
- SH/T 3046-2024 石油化工立式圓筒形鋼制焊接儲罐設(shè)計規(guī)范(正式版)
- 六年級數(shù)學(xué)質(zhì)量分析及改進措施
- 一年級下冊數(shù)學(xué)口算題卡打印
- 真人cs基于信號發(fā)射的激光武器設(shè)計
- 【閱讀提升】部編版語文五年級下冊第三單元閱讀要素解析 類文閱讀課外閱讀過關(guān)(含答案)
- 四年級上冊遞等式計算練習(xí)200題及答案
- 法院后勤部門述職報告
- 2024年國信證券招聘筆試參考題庫附帶答案詳解
- 道醫(yī)館可行性報告
評論
0/150
提交評論