C++程序設(shè)計 第11章 繼承和派生_第1頁
C++程序設(shè)計 第11章 繼承和派生_第2頁
C++程序設(shè)計 第11章 繼承和派生_第3頁
C++程序設(shè)計 第11章 繼承和派生_第4頁
C++程序設(shè)計 第11章 繼承和派生_第5頁
已閱讀5頁,還剩94頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第十一章第十一章 繼承和派生繼承和派生本章主要內(nèi)容n類之間的關(guān)系類之間的關(guān)系n基類和派生類基類和派生類n基類的初始化基類的初始化n繼承的應(yīng)用實例繼承的應(yīng)用實例n多繼承多繼承n繼承時的構(gòu)造函數(shù)繼承時的構(gòu)造函數(shù)或者: class 類名 private: 私有的數(shù)據(jù)和成員函數(shù); public: 公有的數(shù)據(jù)和成員函數(shù); 相關(guān)知識說明nclass是定義類的關(guān)鍵字。n是一個標(biāo)識符,用于唯一標(biāo)識一個類。n類的說明部分,說明該類的所有成員。n類的成員包括數(shù)據(jù)成員和成員函數(shù)兩部分。n類的成員從訪問權(quán)限上分有以下三類:n公有的(public)n私有的(private)n保護(hù)的(protected)n其中默認(rèn)為pr

2、ivate權(quán)限。n公有的成員(public)n可以被程序中的任何代碼訪問;n私有的成員(private)n只能被類本身的成員函數(shù)及友元類的成員函數(shù)訪問,其他類的成員函數(shù),包括其派生類的成員函數(shù)都不能訪問它們;n保護(hù)的成員(protected)n與私有成員類似,只是除了類本身的成員函數(shù)和說明為友元類的成員函數(shù)可以訪問保護(hù)成員外,該類的派生類的成員也可以訪問。11.1 11.1 類之間的關(guān)系類之間的關(guān)系 不具有對稱性不具有對稱性 不是所有植物都屬于蕨類傳遞性傳遞性 高等植物、蕨類植物、芒萁都是植物,具有植物的共同特征 植物植物 低等植物低等植物高等植物高等植物藻類藻類菌類菌類地衣類地衣類苔蘚類苔蘚

3、類蕨類蕨類裸子類裸子類被子類被子類地錢地錢小金發(fā)草小金發(fā)草毛蕨毛蕨芒萁芒萁杉木杉木柏木柏木荔枝荔枝橘子橘子1.1.繼承是指一個類從另一個或另一些類獲得了一些基本性質(zhì),并在此基礎(chǔ)上增加了自身的一些特殊性質(zhì)。2.2.繼承是建立在類的一般化結(jié)構(gòu)(通用特殊結(jié)構(gòu))基礎(chǔ)上的。也即特殊類繼承了一般類的性質(zhì)。一般類基類,或超類。特殊類派生類,或子類。派生類是基類的具體化,而基類則是派生類的抽象11.1 11.1 類之間的繼承關(guān)系類之間的繼承關(guān)系 3. 3. 繼承的關(guān)鍵成分(1)實體所具有的共性(2)實體間的區(qū)別,也即實體自身所具有的個性。 例如,正方形具有與四邊形相同的性質(zhì)。 例如,正方形的四條邊必須等長。(

4、3)實體之間存在一般特殊關(guān)系,從而可以建立層次結(jié)構(gòu)。11.1 11.1 類之間的關(guān)系類之間的關(guān)系 繼承與派生問題舉例工具車轎車面包車小汽車卡車旅行車汽車汽車交通工具交通工具11.1 11.1 類之間的關(guān)系類之間的關(guān)系 繼承與派生問題舉例猴猴 子子獅 子虎獵 豹貓貓鳥鳥動動 物物貓科貓科11.1 11.1 類之間的關(guān)系類之間的關(guān)系 繼承與派生問題舉例圓圓矩形矩形幾何形狀幾何形狀11.1 11.1 類之間的關(guān)系類之間的關(guān)系 11.1 11.1 類之間的關(guān)系類之間的關(guān)系 繼承繼承 是類之間定義的一種重要關(guān)系 一個 B 類繼承A類,或稱從類 A 派生類 B 類 A 稱為基類(父類),類 B 稱為派生類

5、(子類)AB1B2C1C2C3B1,B2 的基類的基類A 的派生類的派生類C1,C2,C3 的基類的基類A 的派生類(單繼承)的派生類(單繼承)C3的基類的基類B1,B2 的派生類(多繼承)的派生類(多繼承)B1 的派生類的派生類類繼承關(guān)系的語法形式類繼承關(guān)系的語法形式class 派生類名 : 基類名表 數(shù)據(jù)成員和成員函數(shù)聲明 ;11.2 11.2 基類和派生類基類和派生類class student1:public student void display_1() cout“age:”ageendl; cout“address:” address endl; Private: int age;

6、 string addr; 類繼承關(guān)系的語法形式類繼承關(guān)系的語法形式class 派生類名 : 基類名表基類名表 數(shù)據(jù)成員和成員函數(shù)聲明 ;11.2 11.2 基類和派生類基類和派生類基類名表基類名表 構(gòu)成訪問控制 基類名1, 訪問控制 基類名2 , , 訪問控制 基類名n類繼承關(guān)系的語法形式類繼承關(guān)系的語法形式class 派生類名 : 基類名表 數(shù)據(jù)成員和成員函數(shù)聲明 ;11.2 11.2 基類和派生類基類和派生類基類名表 構(gòu)成訪問控制訪問控制 基類名1, 訪問控制訪問控制 基類名2 , , 訪問控制訪問控制 基類名n訪問控制訪問控制 表示派生類對基類的繼承方式,使用關(guān)鍵字: 公有繼承 私有繼

7、承 保護(hù)繼承派生類的構(gòu)成派生類的構(gòu)成 基類基類 派生類派生類Student類int num;char name10;char sex;void display();數(shù)數(shù)據(jù)據(jù)成成員員成員成員函數(shù)函數(shù)Student1類int num;char name10;char sex;void display();int age;char addr30;void display();新新增增繼承繼承11.2 11.2 基類和派生類基類和派生類派生類對基類成員的使用,與繼承訪問控制和基類中成員性質(zhì)有關(guān)公有繼承公有繼承基類的公有成員派生類的公有成員 基類的保護(hù)成員派生類的保護(hù)成員私有繼承私有繼承 基類的公有成員

8、和保護(hù)成員派生類的私有成員保護(hù)繼承保護(hù)繼承 基類的公有成員和保護(hù)成員派生類的保護(hù)成員不論種方式繼承基類,派生類都不能直接使用基類的私有成員 7.2.1 訪問控制11.2.1 11.2.1 訪問控制訪問控制繼承方式繼承方式基類成員的訪基類成員的訪問權(quán)限問權(quán)限派生類對基類成員的訪問派生類對基類成員的訪問權(quán)限權(quán)限publicpublic公有繼承公有繼承publicpublicprivateprivateprotectedprotectedpublicpublic不可見不可見protectedprotectedprivateprivate私有繼承私有繼承publicpublicprivatepriva

9、teprotectedprotectedprivateprivate不可見不可見privateprivateprotectedprotected保護(hù)繼承保護(hù)繼承publicpublicprivateprivateprotectedprotectedprotectedprotected不可見不可見protectedprotected7.2.1 訪問控制1.1.公有繼承公有繼承public 成員成員 public 成員成員protected 成員成員 protected 成員成員private 成員成員public 成員成員protected 成員成員private 成員成員基類基類派生類派生類#

10、includeclass A public : void get_XY() cout x y ; void put_XY() cout x = x , y = y n ; protected: int x, y ;class B : public A public : int get_S() return s ; ; void make_S() s = x * y ; ; / 使用基類數(shù)據(jù)成員使用基類數(shù)據(jù)成員x,y protected: int s;class C : public B public : void get_H() cout h ; int get_V() return v ;

11、void make_V() make_S(); v = get_S() * h ; / 使用基類成員函數(shù)使用基類成員函數(shù) protected: int h, v;例例 公有繼承的測試公有繼承的測試 7.2.1 7.2.1 訪問控制訪問控制class Aclass C : public Bclass B : public Avoid main() A objA ; B objB ; C objC ; cout It is object_A :n ; objA.get_XY() ; objA.put_XY() ; cout It is object_B :n ; objB.get_XY() ; o

12、bjB.make_S() ; cout S = objB.get_S() endl ; cout It is object_C :n ; objC.get_XY() ; objC.get_H(); objC.make_V() ; cout V = objC.get_V() endl ;objA.yobjA.xobjAobjB.sobjB.yobjB.xobjBobjC.hobjC.vobjC.sobjC.yobjC.xobjCx y sh v 7.2.1 7.2.1 訪問控制訪問控制例例 公有繼承的測試公有繼承的測試 7.2.1 訪問控制public 成員成員protected 成員成員pri

13、vate 成員成員public 成員成員protected 成員成員private 成員成員基類基類派生類派生類private 成員成員private 成員成員2.2.私有繼承私有繼承#includeclass A public : void get_XY() cout x y ; void put_XY() cout x = x , y = y n ; protected: int x, y ;class B : private A public : int get_S() return s ; void make_S() get_XY(); s = x * y ; private: int

14、 s ;void main() B objB ; cout It is object_B :n ; objB.make_S() ; cout S = objB.get_S() endl ; 例例 私有繼承的測試私有繼承的測試 class B : private Aclass A objB.sobjB.yobjB.xobjBprivate成員成員7.2.1 7.2.1 訪問控制訪問控制#includeclass A public : void get_XY() cout x y ; void put_XY() cout x = x , y = y n ; protected: int x, y

15、;class B : private A public : int get_S() return s ; void make_S() get_XY(); s = x * y ; private: int s ;void main() B objB ; cout It is object_B :n ; objB.make_S() ; cout S = objB.get_S() endl ; class B : private Aclass A objB.sobjB.yobjB.xobjBprivate成員成員7.2.1 7.2.1 訪問控制訪問控制例例 私有繼承的測試私有繼承的測試 #inclu

16、declass A public: A() x=1; int out() return x ; void addX() x+; private: int x ; ;class B : public A public: B() y=1; int out() return y ; void addY() y+; private:int y ; ;void main() A a ; B b ; b.addX() ; b.addY() ; cout a.x= a.out() endl ; cout b.x= b.A:out() endl ; cout b.y= b.out() endl ;例例 私有數(shù)

17、據(jù)成員的測試私有數(shù)據(jù)成員的測試 class B : public Aclass A 基類的私有數(shù)據(jù)成員基類的私有數(shù)據(jù)成員不能在派生類中直接訪問不能在派生類中直接訪問但派生類對象建立私有數(shù)據(jù)空間但派生類對象建立私有數(shù)據(jù)空間 b.xa.xb.y7.2.1 7.2.1 訪問控制訪問控制#includeclass A public: A() x=1; int out() return x ; void addX() x+; private: int x ; ;class B : public A public: B() y=1; int out() return y ; void addY() y+;

18、 private:int y ; ;void main() A a ; cout a.x= a.out() endl ; B b ; b.addX() ; b.addY() ; cout b.x= b.A:out() endl ; cout b.y= b.out() endl ;class B : public Aclass A b.xa.xb.y7.2.1 7.2.1 訪問控制訪問控制例例 私有數(shù)據(jù)成員的測試私有數(shù)據(jù)成員的測試7.2.1 訪問控制public 成員成員protected 成員成員private 成員成員public 成員成員protected 成員成員private 成員成員

19、基類基類派生類派生類protected 成員成員protected 成員成員3.3.保護(hù)繼承保護(hù)繼承 派生類定義了與基類同名的成員,在派生類中訪問同名成員派生類定義了與基類同名的成員,在派生類中訪問同名成員 時屏蔽了基類的同名成員時屏蔽了基類的同名成員 在在派生類中使用基類的同名成員,顯式地使用類名限定符:派生類中使用基類的同名成員,顯式地使用類名限定符:類名類名 : 成員成員 7.2.2 重名成員11.2.2 11.2.2 重名成員重名成員例:例:class base public : int a , b ; ;class derived : public base public : int

20、 b , c ; ;void f () derived d ; d . a = 1 ; d . base : b = 2 ; d . b = 3 ; d . c = 4 ;7.2.2 重名成員base a b 4321derived derived a b 基類成員的作用域延伸到所有派生類基類成員的作用域延伸到所有派生類派生類的重名成員屏蔽基類的同名成員派生類的重名成員屏蔽基類的同名成員1.1.重名數(shù)據(jù)成員重名數(shù)據(jù)成員/例例#includeclass A public: int a1, a2 ; A( int i1=0, int i2=0 ) a1 = i1; a2 = i2; void pr

21、int() cout a1= a1 t a2= a2 endl ; ;class B : public A public: int b1, b2 ; B( int j1=1, int j2=1 ) b1 = j1; b2 = j2; void print()/定義同名函數(shù)定義同名函數(shù) cout b1= b1 t b2= b2 endl ; void printAB() A:print() ;/派生類對象調(diào)用基類版本同名成員函數(shù)派生類對象調(diào)用基類版本同名成員函數(shù) print() ;/派生類對象調(diào)用自身的成員函數(shù)派生類對象調(diào)用自身的成員函數(shù) ;void main() B b ; b.A:print

22、();b.printAB(); 7.2.2 重名成員2.2.重名成員函數(shù)重名成員函數(shù)類型兼容規(guī)則n一個公有派生類的對象在使用上可以被當(dāng)作基類的對象,反之則禁止。具體表現(xiàn)在:n派生類的對象可以被賦值給基類對象。n派生類的對象可以初始化基類的引用。n指向基類的指針也可以指向派生類。n通過基類對象名、指針只能使用從基類繼承的成員例 類型兼容規(guī)則舉例#include using namecpace std;class B0/基類B0聲明 public:void display()coutB0:display()endl;/公有成員函數(shù);class B1: public B0 public:void d

23、isplay()coutB1:display()endl;class D1: public B1public:void display()coutD1:display()display();/對象指針-成員名 int main() /主函數(shù) B0 b0;/聲明B0類對象B1 b1;/聲明B1類對象D1 d1;/聲明D1類對象B0 *p;/聲明B0類指針p=&b0; /B0類指針指向B0類對象fun(p);p=&b1; /B0類指針指向B1類對象fun(p);p=&d1; /B0類指針指向D1類對象fun(p);運行結(jié)果:B0:display()B0:displaydis

24、play()B0:display()11.3 11.3 基類的初始化基類的初始化 建立一個類層次后,通常創(chuàng)建某個派生類的對象,包括使用基類的數(shù)據(jù)和函數(shù) C+提供一種機(jī)制,在創(chuàng)建派生類對象時用指定參數(shù)調(diào)用基類的構(gòu)造函數(shù)來初始化派生類繼承基類的數(shù)據(jù) 派生類構(gòu)造函數(shù)聲明為派生類構(gòu)造函數(shù)派生類構(gòu)造函數(shù) ( 變元表變元表 ) : 基類基類 ( 變元表變元表 ) , 對象成員對象成員1( 變元表變元表 ) 對象成員對象成員n ( 變元表變元表 ) ; 構(gòu)造函數(shù)執(zhí)行順序:基類 對象成員 派生類/ 例例 調(diào)用構(gòu)造函數(shù)順序測試,構(gòu)造函數(shù)無參數(shù)調(diào)用構(gòu)造函數(shù)順序測試,構(gòu)造函數(shù)無參數(shù)#include class Ba

25、se public : Base ( ) cout Base created.n ; ;class D_class : public Base public : D_class ( ) cout D_class created.n ; ;void main ( ) D_class d1 ; 7.3 基類的初始化#include class parent_class int data1 , data2 ; public : parent_class ( int p1 , int p2 ) data1 = p1; data2 = p2; int inc1 () return + data1; in

26、t inc2 () return + data2 ; void display () cout data1= data1 , data2= data2 endl ; ;class derived_class : private parent_class int data3 ; parent_class data4 ; public: derived_class ( int p1 , int p2 , int p3 , int p4 , int p5 ): parent_class ( p1 , p2 ) , data4 ( p3 , p4 ) data3 = p5 ; int inc1 ( )

27、 return parent_class : inc1 ( ) ; int inc3 ( ) return + data3 ; void display ( ) parent_class : display ( ) ; data4.display ( ) ; cout data3= data3 endl ; ;void main ( ) derived_class d1 ( 17 , 18 , 1 , 2 , -5 ) ; d1 . inc1 ( ) ; d1 . display ( ) ; 例例 帶參數(shù)構(gòu)造函數(shù)調(diào)用順序測試帶參數(shù)構(gòu)造函數(shù)調(diào)用順序測試7.3 7.3 基類的初始化基類的初始化11

28、.4 11.4 繼承的應(yīng)用實例繼承的應(yīng)用實例PointCircleCylinderclass Point friend ostream &operator (ostream &, const Point &); public: Point( int = 0, int = 0 ) ;/ 帶默認(rèn)參數(shù)的構(gòu)造函數(shù)帶默認(rèn)參數(shù)的構(gòu)造函數(shù) void setPoint( int, int ) ;/ 對點坐標(biāo)數(shù)據(jù)賦值對點坐標(biāo)數(shù)據(jù)賦值 int getX() const return x ; int getY() const return y ; protected: int x, y;/

29、Point類的數(shù)據(jù)成員類的數(shù)據(jù)成員;class Circle : public Point friend ostream &operator (ostream &, const Circle &);/ 友員函數(shù)友員函數(shù) public: Circle(double r=0.0, int x=0, int y=0);/ 構(gòu)造函數(shù)構(gòu)造函數(shù) void setRadius(double); /*置半徑置半徑*/ double getRadius() const; /*返回半徑返回半徑*/ double area() const;/ 返回面積返回面積 protected: doub

30、le radius;/ 數(shù)據(jù)成員,半徑數(shù)據(jù)成員,半徑;class Cylinder:public Circle friend ostream & operator(ostream &, const Cylinder &); / 友員函數(shù)友員函數(shù) public: Cylinder(double h=0.0, double r=0.0, int x=0, int y=0); / 構(gòu)造函數(shù)構(gòu)造函數(shù) void setHeight(double); /* 置高度值置高度值*/ double getHeight() const; /* 返回高度返回高度值值*/ double are

31、a() const; /* 返回面積返回面積*/ double volume() const; /* 返回體積返回體積*/ protected: double height;/ 數(shù)據(jù)成員,高度數(shù)據(jù)成員,高度;7.4 繼承的應(yīng)用實例/ Point 類的成員函數(shù)類的成員函數(shù) / 構(gòu)造函數(shù),調(diào)用成員函數(shù)對構(gòu)造函數(shù),調(diào)用成員函數(shù)對 x,y作初始化作初始化Point:Point ( int a, int b ) setPoint ( a , b ) ; / 對數(shù)據(jù)成員置值對數(shù)據(jù)成員置值void Point : setPoint ( int a, int b ) x = a ; y = b ; / 重載插

32、入算符,輸出對象數(shù)據(jù)重載插入算符,輸出對象數(shù)據(jù)ostream &operator ( ostream &output , const Point &p ) output p.x , p.y = 0 ? r : 0 ); / 返回半徑值返回半徑值double Circle:getRadius() const return radius; / 計算并返回面積值計算并返回面積值double Circle:area() const return 3.14159 * radius * radius ; / 輸出圓心坐標(biāo)和半徑值輸出圓心坐標(biāo)和半徑值ostream & ope

33、rator ( ostream &output, const Circle &c) output Center = c.x , c.y ; Radius = setiosflags(ios:fixed|ios:showpoint) setprecision(2) = 0 ? h : 0 ); / 返回高度值返回高度值double Cylinder:getHeight() const return height; / 計算并返回圓柱體的表面積計算并返回圓柱體的表面積d o u b l e C y l i n d e r : : a r e a ( ) c o n s t r e

34、t u r n 2*Circle:area()+2*3.14159*radius*height; / 計算并返回圓柱體的體積計算并返回圓柱體的體積double Cylinder:volume() const return Circle:area()*height; / 輸出數(shù)據(jù)成員圓心坐標(biāo)、半徑和高度值輸出數(shù)據(jù)成員圓心坐標(biāo)、半徑和高度值ostream &operator ( ostream &output, const Cylinder &cy ) output Center = cy.x , cy.y ; Radius = setiosflags(ios:fixed|

35、ios:showpoint) setprecision(2) cy.radius ; Height = cy.height endl ; return output; 7.4 7.4 繼承的應(yīng)用實例繼承的應(yīng)用實例#include #include void main() Point p ( 72, 115 ) ;/定義點對象并初始化定義點對象并初始化 cout The initial location of p is p endl ; p.setPoint ( 10, 10 ) ;/置點的新數(shù)據(jù)值置點的新數(shù)據(jù)值 cout nThe new location of p is p endl ;/輸

36、出數(shù)據(jù)輸出數(shù)據(jù) Circle c ( 2.5, 37, 43 ) ;/定義圓對象并初始化定義圓對象并初始化 coutnThe initial location and radius of c arencnArea = c.area()n ; /置圓的新數(shù)據(jù)值置圓的新數(shù)據(jù)值 c.setRadius ( 4.25 ) ; c.setPoint ( 2, 2 ) ; /輸出圓心坐標(biāo)和圓面積輸出圓心坐標(biāo)和圓面積 coutnThe new location and radius of c arencnArea = c.area() n ; Cylinder cyl ( 5.7, 2.5, 12, 23

37、) ;/定義圓柱體對象并初始化定義圓柱體對象并初始化 /輸出圓柱體各數(shù)據(jù)和表面積,體積輸出圓柱體各數(shù)據(jù)和表面積,體積 cout nThe initial location, radius ang height of cyl aren cyl Area = cyl.area() nVolume = cyl.volume() n; /置圓柱體的新數(shù)據(jù)值置圓柱體的新數(shù)據(jù)值 cyl.setHeight ( 10 ) ; cyl.setRadius ( 4.25 ) ; cyl.setPoint ( 2, 2 ) ; cout nThe new location, radius ang height o

38、f cyl aren cyl Area = cyl.area() nVolume = cyl.volume() n ; 7.4 繼承的應(yīng)用實例TaskDisplayedSatelliteTaskSatellite 一個類有多個直接基類的繼承關(guān)系稱為一個類有多個直接基類的繼承關(guān)系稱為多繼承多繼承 多繼承聲明語法多繼承聲明語法class 派生類名派生類名 : 訪問控制訪問控制 基類名基類名1 , 訪問控制訪問控制 基類名基類名2 , , 訪問控制訪問控制 基類名基類名n 數(shù)據(jù)成員和成員函數(shù)聲明數(shù)據(jù)成員和成員函數(shù)聲明 ;7.5 多繼承class C : public A ,public Bclass

39、 Aclass B 類 C 可以根據(jù)訪問控制同時繼承類 A 和類 B 的成員,并添加 自己的成員7.5 多繼承 多個基類的派生類構(gòu)造函數(shù)可以用初始式調(diào)用基類構(gòu)造函數(shù)初始化多個基類的派生類構(gòu)造函數(shù)可以用初始式調(diào)用基類構(gòu)造函數(shù)初始化數(shù)據(jù)成員數(shù)據(jù)成員執(zhí)行順序與單繼承構(gòu)造函數(shù)情況類似。多個直接基類構(gòu)造函數(shù)執(zhí)行執(zhí)行順序與單繼承構(gòu)造函數(shù)情況類似。多個直接基類構(gòu)造函數(shù)執(zhí)行順序取決于定義派生類時指定的各個繼承基類的順序。順序取決于定義派生類時指定的各個繼承基類的順序。 一個派生類對象擁有多個直接或間接基類的成員。不同名成員訪問一個派生類對象擁有多個直接或間接基類的成員。不同名成員訪問不會出現(xiàn)二義性。如果不同的

40、基類有同名成員,派生類對象訪問時應(yīng)不會出現(xiàn)二義性。如果不同的基類有同名成員,派生類對象訪問時應(yīng)該加以識別。該加以識別。 11.5.1 11.5.1 多繼承的派生類構(gòu)造和訪問多繼承的派生類構(gòu)造和訪問7.5.1 多繼承的派生類構(gòu)造和訪問class Derived : public Base1, public Base2 friend ostream &operator ( ostream &, const Derived & ) ; public : Derived ( int, char, double ) ; double getReal() const ; priva

41、te : double real ;class Base1 public: Base1(int x) value = x ; int getData() const return value ; protected: int value;class Base2 public: Base2(char c) letter=c; char getData() const return letter; protected: char letter;多繼承的簡單應(yīng)用多繼承的簡單應(yīng)用 7.5.1 多繼承的派生類構(gòu)造和訪問多繼承的派生類構(gòu)造和訪問多繼承的簡單應(yīng)用多繼承的簡單應(yīng)用 class Base1 pu

42、blic: Base1(int x) value = x ; int getData() const return value ; protected: int value;class Base2 public: Base2(char c) letter=c; char getData() const return letter; protected: char letter;class Derived : public Base1, public Base2 friend ostream &operator ( ostream &, const Derived & )

43、 ; public : Derived ( int, char, double ) ; double getReal() const ; private : double real ;void main() Base1 b1 ( 10 ) ; Base2 b2 ( k ) ; Derived d ( 5, A, 2.5 ) ; : return ;K2.5A510value letter realBasc1 b1Basc2 b2Derived d7.5.1 多繼承的派生類構(gòu)造和訪問多繼承的派生類構(gòu)造和訪問n基類的構(gòu)造函數(shù)不被繼承,派生類中需要聲明自基類的構(gòu)造函數(shù)不被繼承,派生類中需要聲明自己的

44、構(gòu)造函數(shù)。己的構(gòu)造函數(shù)。n聲明構(gòu)造函數(shù)時,只需要對本類中新增成員進(jìn)行聲明構(gòu)造函數(shù)時,只需要對本類中新增成員進(jìn)行初始化,對繼承來的基類成員的初始化,自動調(diào)初始化,對繼承來的基類成員的初始化,自動調(diào)用基類構(gòu)造函數(shù)完成。用基類構(gòu)造函數(shù)完成。n派生類的構(gòu)造函數(shù)需要給基類的構(gòu)造函數(shù)傳遞參派生類的構(gòu)造函數(shù)需要給基類的構(gòu)造函數(shù)傳遞參數(shù)數(shù)派生類名派生類名:派生類名派生類名(基類所需的形參,本類成員所需的形參基類所需的形參,本類成員所需的形參):基類名基類名(參數(shù)表參數(shù)表) 本類成員初始化賦值語句;本類成員初始化賦值語句;11.6.1 11.6.1 單一繼承時的構(gòu)造函數(shù)單一繼承時的構(gòu)造函數(shù)舉例舉例#includ

45、eusing namespace std;class B public: B(); B(int i); B(); void Print() const; private: int b;11.6.1 11.6.1 單一繼承時的構(gòu)造函數(shù)單一繼承時的構(gòu)造函數(shù)B:B() b=0;coutBs default constructor called.endl;B:B(int i) b=i; coutBs constructor called. endl;B:B() coutBs destructor called.endl; void B:Print() const coutbendl; 54class

46、C:public B public: C(); C(int i,int j); C(); void Print() const;private: int c;55C:C() c=0;coutCs default constructor called.endl;C:C(int i,int j):B(i) c=j;coutCs constructor called.endl;C:C() coutCs destructor called.endl; void C:Print() const B:Print(); coutcendl; int main() C obj(5,6); obj.Print(

47、); 56派生類名派生類名:派生類名派生類名(基類基類1形參,基類形參,基類2形參,形參,.基類基類n形參,本類形形參,本類形參參):基類名基類名1(參數(shù)參數(shù)), 基類名基類名2(參數(shù)參數(shù)), .基類名基類名n(參數(shù)參數(shù)) 本類成員初始化賦值語句;本類成員初始化賦值語句;11.6.2 11.6.2 多繼承時的構(gòu)造函數(shù)多繼承時的構(gòu)造函數(shù)n當(dāng)基類中聲明有默認(rèn)形式的構(gòu)造函數(shù)或未聲明構(gòu)造函數(shù)時,派當(dāng)基類中聲明有默認(rèn)形式的構(gòu)造函數(shù)或未聲明構(gòu)造函數(shù)時,派生類構(gòu)造函數(shù)可以不向基類構(gòu)造函數(shù)傳遞參數(shù)。生類構(gòu)造函數(shù)可以不向基類構(gòu)造函數(shù)傳遞參數(shù)。n若基類中未聲明構(gòu)造函數(shù),派生類中也可以不聲明,全采用默若基類中未聲明

48、構(gòu)造函數(shù),派生類中也可以不聲明,全采用默認(rèn)形式構(gòu)造函數(shù)。認(rèn)形式構(gòu)造函數(shù)。n當(dāng)基類聲明有帶形參的構(gòu)造函數(shù)時,派生類也應(yīng)聲明帶形參的當(dāng)基類聲明有帶形參的構(gòu)造函數(shù)時,派生類也應(yīng)聲明帶形參的構(gòu)造函數(shù),并將參數(shù)傳遞給基類構(gòu)造函數(shù)。構(gòu)造函數(shù),并將參數(shù)傳遞給基類構(gòu)造函數(shù)。11.6.2 11.6.2 派生類與基類的構(gòu)造函數(shù)派生類與基類的構(gòu)造函數(shù) 派生類名派生類名:派生類名派生類名(基類基類1形參,基類形參,基類2形參,形參,.基類基類n形參,本形參,本類形參類形參):基類名基類名1(參數(shù)參數(shù)), 基類名基類名2(參數(shù)參數(shù)), .基類名基類名n(參數(shù)參數(shù)),對象數(shù),對象數(shù)據(jù)成員的初始化據(jù)成員的初始化 本類成員初

49、始化賦值語句;本類成員初始化賦值語句;11.6.3 11.6.3 多繼承且有內(nèi)嵌對象時的構(gòu)造函數(shù)多繼承且有內(nèi)嵌對象時的構(gòu)造函數(shù)1 調(diào)用基類構(gòu)造函數(shù),調(diào)用順序按照它們被繼承時聲明的順序調(diào)用基類構(gòu)造函數(shù),調(diào)用順序按照它們被繼承時聲明的順序(從左向右)。(從左向右)。2 調(diào)用成員對象的構(gòu)造函數(shù),調(diào)用順序按照它們在類中聲明的調(diào)用成員對象的構(gòu)造函數(shù),調(diào)用順序按照它們在類中聲明的順序。順序。3 派生類的構(gòu)造函數(shù)體中的內(nèi)容。派生類的構(gòu)造函數(shù)體中的內(nèi)容。11.7 11.7 構(gòu)造函數(shù)的調(diào)用順序構(gòu)造函數(shù)的調(diào)用順序拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù)若建立派生類對象時調(diào)用默認(rèn)拷貝構(gòu)造函數(shù),則編譯器將自動調(diào)用若建立派生類對象時調(diào)

50、用默認(rèn)拷貝構(gòu)造函數(shù),則編譯器將自動調(diào)用基類的默認(rèn)拷貝構(gòu)造函數(shù)?;惖哪J(rèn)拷貝構(gòu)造函數(shù)。若編寫派生類的拷貝構(gòu)造函數(shù),則需要為基類相應(yīng)的拷貝構(gòu)造函數(shù)若編寫派生類的拷貝構(gòu)造函數(shù),則需要為基類相應(yīng)的拷貝構(gòu)造函數(shù)傳遞參數(shù)。例如傳遞參數(shù)。例如:C:C(C &c1):B(c1)例例 派生類構(gòu)造函數(shù)舉例派生類構(gòu)造函數(shù)舉例#include using namespace std;class B1/基類基類B1,構(gòu)造函數(shù)有參數(shù),構(gòu)造函數(shù)有參數(shù)public:B1(int i) coutconstructing B1 iendl;class B2/基類基類B2,構(gòu)造函數(shù)有參數(shù),構(gòu)造函數(shù)有參數(shù)public:B2

51、(int j) coutconstructing B2 jendl;class B3/基類基類B3,構(gòu)造函數(shù)無參數(shù),構(gòu)造函數(shù)無參數(shù)public:B3()coutconstructing B3 *endl;class C: public B2, public B1, public B3 public:/派生類的公有成員派生類的公有成員C(int a, int b, int c, int d): B1(a),memberB2(d),memberB1(c),B2(b) private:/派生類的私有對象成員派生類的私有對象成員B1 memberB1;B2 memberB2;B3 memberB3;i

52、nt main() C obj(1,2,3,4); 運行結(jié)果:constructing B2 2constructing B1 1constructing B3 *constructing B1 3constructing B2 4constructing B3 *64繼承時的析構(gòu)函數(shù)繼承時的析構(gòu)函數(shù)n析構(gòu)函數(shù)也不被繼承,派生類自行聲明析構(gòu)函數(shù)也不被繼承,派生類自行聲明n聲明方法與一般(無繼承關(guān)系時)類的析構(gòu)函數(shù)相同。聲明方法與一般(無繼承關(guān)系時)類的析構(gòu)函數(shù)相同。n不需要顯式地調(diào)用基類的析構(gòu)函數(shù),系統(tǒng)會自動隱式不需要顯式地調(diào)用基類的析構(gòu)函數(shù),系統(tǒng)會自動隱式調(diào)用。調(diào)用。n析構(gòu)函數(shù)的調(diào)用次序與構(gòu)

53、造函數(shù)相反。析構(gòu)函數(shù)的調(diào)用次序與構(gòu)造函數(shù)相反。例例 派生類析構(gòu)函數(shù)舉例派生類析構(gòu)函數(shù)舉例#include using namecpace std;class B1/基類基類B1聲明聲明 public:B1(int i) coutconstructing B1 iendl;B1() coutdestructing B1 endl;class B2/基類基類B2聲明聲明public:B2(int j) coutconstructing B2 jendl;B2() coutdestructing B2 endl;class B3/基類基類B3聲明聲明public:B3()coutconstructi

54、ng B3 *endl;B3() coutdestructing B3 endl;class C: public B2, public B1, public B3public:C(int a, int b, int c, int d): B1(a),memberB2(d),memberB1(c),B2(b)private:B1 memberB1;B2 memberB2;B3 memberB3;int main() C obj(1,2,3,4); 67例例 運行結(jié)果運行結(jié)果constructing B2 2constructing B1 1constructing B3 *constructin

55、g B1 3constructing B2 4constructing B3 *destructing B3destructing B2destructing B1destructing B3destructing B1destructing B2同名隱藏規(guī)則同名隱藏規(guī)則當(dāng)派生類與基類中有相同成員時:當(dāng)派生類與基類中有相同成員時:n若未強行指名,則通過派生類對象使用的是派生類中若未強行指名,則通過派生類對象使用的是派生類中的同名成員。的同名成員。n如要通過派生類對象訪問基類中被覆蓋的同名成員,如要通過派生類對象訪問基類中被覆蓋的同名成員,應(yīng)使用基類名限定。應(yīng)使用基類名限定。例例 多繼承同名隱藏

56、舉例多繼承同名隱藏舉例#include using namespace std;class B1/聲明基類聲明基類B1 public:/外部接口外部接口int nV;void fun() coutMember of B1endl;class B2/聲明基類聲明基類B2 public:/外部接口外部接口int nV;void fun()coutMember of B2endl;class D1: public B1, public B2 public:int nV;/同名數(shù)據(jù)成員同名數(shù)據(jù)成員void fun()coutMember of D1endl;/同名函數(shù)成員同名函數(shù)成員;int main

57、() D1 d1;d1.nV=1; /對象名對象名.成員名標(biāo)識成員名標(biāo)識, 訪問訪問D1類成員類成員d1.fun(); d1.B1:nV=2;/作用域分辨符標(biāo)識作用域分辨符標(biāo)識, 訪問基類訪問基類B1成員成員d1.B1:fun();d1.B2:nV=3;/作用域分辨符標(biāo)識作用域分辨符標(biāo)識, 訪問基類訪問基類B2成員成員d1.B2:fun();二義性問題二義性問題n在多繼承時,基類與派生類之間,或基類之間出現(xiàn)同名成員時,在多繼承時,基類與派生類之間,或基類之間出現(xiàn)同名成員時,將出現(xiàn)訪問時的二義性(不確定性)將出現(xiàn)訪問時的二義性(不確定性)采用虛函數(shù)或同名隱采用虛函數(shù)或同名隱藏規(guī)則來解決。藏規(guī)則來

58、解決。n當(dāng)派生類從多個基類派生,而這些基類又從同一個基類派生,當(dāng)派生類從多個基類派生,而這些基類又從同一個基類派生,則在訪問此共同基類中的成員時,將產(chǎn)生二義性則在訪問此共同基類中的成員時,將產(chǎn)生二義性采用虛基采用虛基類來解決。類來解決。B1B2B3AC二義性問題舉例(一)二義性問題舉例(一)class A public: void f();class B public: void f(); void g();class C: public A, piblic B public: void g(); void h();如果聲明:如果聲明:C c1;則則 c1.f(); 具有二義性具有二義性而而

59、c1.g(); 無二義性(同名覆蓋)無二義性(同名覆蓋)二義性的解決方法二義性的解決方法n解決方法一:用類名來限定解決方法一:用類名來限定c1.A:f() 或或 c1.B:f()n解決方法二:同名覆蓋解決方法二:同名覆蓋在在C 中聲明一個同名成員函數(shù)中聲明一個同名成員函數(shù)f(),f()再根據(jù)需要調(diào)用再根據(jù)需要調(diào)用 A:f() 或或 B:f()二義性問題舉例(二)二義性問題舉例(二)class B public: int b;class B1 : public B private: int b1;class B2 : public B private: int b2;class C : publ

60、ic B1,public B2 public: int f(); private: int d;派生類派生類C C的對象的存儲結(jié)構(gòu)示意圖:的對象的存儲結(jié)構(gòu)示意圖:bb1bb2dB類成員B類成員B1類成員B2類成員C類對象有二義性:有二義性:C c;c.bc.B:b無二義性:無二義性:c.B1:bc.B2:b7611.5.2 11.5.2 虛基類虛基類 如果一個派生類從多個基類派生,而這些基類又有一個共同如果一個派生類從多個基類派生,而這些基類又有一個共同 的基類,則在對該基類中聲明的名字進(jìn)行訪問時,可能產(chǎn)生的基類,則在對該基類中聲明的名字進(jìn)行訪問時,可能產(chǎn)生 二義性二義性7.5.2 虛基類例如:例如:class B public : int b ; ;class B1 : public B private : int b1 ; ;class B2 : public B private : i

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論