第12章組合與繼承_第1頁(yè)
第12章組合與繼承_第2頁(yè)
第12章組合與繼承_第3頁(yè)
第12章組合與繼承_第4頁(yè)
已閱讀5頁(yè),還剩109頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 1v組合組合 v繼承繼承 v虛函數(shù)與多態(tài)性虛函數(shù)與多態(tài)性v純虛函數(shù)與抽象類(lèi)純虛函數(shù)與抽象類(lèi) v多繼承多繼承 v面向?qū)ο笤O(shè)計(jì)范例面向?qū)ο笤O(shè)計(jì)范例程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 2v繼承是面向?qū)ο蟪绦蛟O(shè)計(jì)的一個(gè)重要特征,繼承是面向?qū)ο蟪绦蛟O(shè)計(jì)的一個(gè)重要特征,它允許在已有類(lèi)的基礎(chǔ)上創(chuàng)建新的類(lèi)它允許在已有類(lèi)的基礎(chǔ)上創(chuàng)建新的類(lèi)v基類(lèi)、父類(lèi)基類(lèi)、父類(lèi)v派生類(lèi)、導(dǎo)出類(lèi)或子類(lèi)派生類(lèi)、導(dǎo)出類(lèi)或子類(lèi)v繼承可以讓程序員在已有類(lèi)的基礎(chǔ)上通過(guò)增繼承可以讓程序員在已有類(lèi)的基礎(chǔ)上通過(guò)增加或修改少量代碼的方法得到新的類(lèi),從而加或修改少量代碼的方法得到新的

2、類(lèi),從而較好地解決代碼重用的問(wèn)題。較好地解決代碼重用的問(wèn)題。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 3v單繼承的格式單繼承的格式v基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性 v派生類(lèi)對(duì)象的構(gòu)造、析構(gòu)與賦值操作派生類(lèi)對(duì)象的構(gòu)造、析構(gòu)與賦值操作 v重定義基類(lèi)的函數(shù)重定義基類(lèi)的函數(shù) v派生類(lèi)作為基類(lèi)派生類(lèi)作為基類(lèi) v將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 4v一般格式:一般格式: class 派生類(lèi)名:派生方法派生類(lèi)名:派生方法 基類(lèi)名基類(lèi)名 /派生類(lèi)新增的數(shù)據(jù)成員和成員函數(shù)派生類(lèi)新增的數(shù)據(jù)成員和成員

3、函數(shù) ;v派生方法:派生方法:1.公有派生公有派生: public2.私有派生:私有派生:private3.保護(hù)派生:保護(hù)派生:protected程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 5class base int x; public: void setx(int k);class derived1:public base int y; public: void sety(int k); Derived1有兩個(gè)數(shù)據(jù)有兩個(gè)數(shù)據(jù)成員:成員:x,y。有兩個(gè)成員函數(shù):有兩個(gè)成員函數(shù):setx和和sety程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 6v派生類(lèi)的成員函數(shù)不能訪問(wèn)基類(lèi)的

4、私有數(shù)派生類(lèi)的成員函數(shù)不能訪問(wèn)基類(lèi)的私有數(shù)據(jù)成員據(jù)成員 vprotected訪問(wèn)特性訪問(wèn)特性 protected成員是一類(lèi)特殊的私有成員,它不成員是一類(lèi)特殊的私有成員,它不可以被全局函數(shù)或其他類(lèi)的成員函數(shù)訪問(wèn),可以被全局函數(shù)或其他類(lèi)的成員函數(shù)訪問(wèn),但能被派生類(lèi)的成員函數(shù)訪問(wèn)但能被派生類(lèi)的成員函數(shù)訪問(wèn) protected成員破壞了類(lèi)的封裝,基類(lèi)的成員破壞了類(lèi)的封裝,基類(lèi)的protected成員改變時(shí),所有派生類(lèi)都要修改成員改變時(shí),所有派生類(lèi)都要修改 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 7v單繼承的格式單繼承的格式v基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性 v派生類(lèi)

5、對(duì)象的構(gòu)造、析構(gòu)與賦值操作派生類(lèi)對(duì)象的構(gòu)造、析構(gòu)與賦值操作 v重定義基類(lèi)的函數(shù)重定義基類(lèi)的函數(shù) v派生類(lèi)作為基類(lèi)派生類(lèi)作為基類(lèi) v將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 8基類(lèi)成員的基類(lèi)成員的訪問(wèn)說(shuō)明符訪問(wèn)說(shuō)明符 繼承類(lèi)型繼承類(lèi)型 public繼承繼承 protected繼承繼承 private繼承繼承public 在派生類(lèi)中為在派生類(lèi)中為public 在派生類(lèi)中為在派生類(lèi)中為protected 在派生類(lèi)中為在派生類(lèi)中為private 可以由任何非可以由任何非static 可以直接由任何非可以直接由任何非static 可

6、以直接由任何非可以直接由任何非static 成員函數(shù)、友元函數(shù)和成員函數(shù)、友元函數(shù)和 成員函數(shù)、友元函數(shù)成員函數(shù)、友元函數(shù) 成員函數(shù)、友元函數(shù)成員函數(shù)、友元函數(shù) 非成員函數(shù)訪問(wèn)非成員函數(shù)訪問(wèn) 訪問(wèn)訪問(wèn) 訪問(wèn)訪問(wèn)protecetd 在派生類(lèi)中為在派生類(lèi)中為proteced 在派生類(lèi)中為在派生類(lèi)中為protected 在派生類(lèi)中在派生類(lèi)中private 可以直接由任何非可以直接由任何非static 成員函數(shù)、友元函數(shù)訪問(wèn)成員函數(shù)、友元函數(shù)訪問(wèn)private 在派生類(lèi)中隱藏在派生類(lèi)中隱藏 在派生類(lèi)中隱藏在派生類(lèi)中隱藏 在派生類(lèi)中隱藏在派生類(lèi)中隱藏 可以通過(guò)基類(lèi)的可以通過(guò)基類(lèi)的public 或或pro

7、tected成員函數(shù)或非成員函數(shù)或非static成員函數(shù)和友元函數(shù)訪問(wèn)成員函數(shù)和友元函數(shù)訪問(wèn)程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 9 Derived1不可訪問(wèn)不可訪問(wèn) Int xprivateInt ypublicSetx()Sety()class base int x; public: void setx(int k);class derived1:public base int y; public: void sety(int k); 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 10v 定義一個(gè)二維平面上的點(diǎn)類(lèi)型,可以設(shè)定義一個(gè)二維平面上的點(diǎn)類(lèi)型,可以設(shè)置點(diǎn)的位置,獲

8、取點(diǎn)的位置。在此基礎(chǔ)置點(diǎn)的位置,獲取點(diǎn)的位置。在此基礎(chǔ)上,擴(kuò)展出一個(gè)三維空間上的點(diǎn)類(lèi)型。上,擴(kuò)展出一個(gè)三維空間上的點(diǎn)類(lèi)型。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 11class point_2d private: int x,y; public: void setpoint2(int a, int b) x = a; y = b; int getx() return x; int gety() return y; ;程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 12class point_3d:public point_2dint z; public: void setpoi

9、nt3(int a,int b,int c) setpoint2(a,b); z=c; int getz() return z; 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 13vpoint_3d的組成:有三個(gè)數(shù)據(jù)成員:的組成:有三個(gè)數(shù)據(jù)成員:x,y和和z,有,有五個(gè)公有的成員函數(shù):五個(gè)公有的成員函數(shù):setpoint2, setpoint3, getx, gety和和getz。vpoint_3d的成員函數(shù)無(wú)法直接訪問(wèn)基類(lèi)的的成員函數(shù)無(wú)法直接訪問(wèn)基類(lèi)的x和和y,因此在因此在setpoint3函數(shù)中必須調(diào)用在函數(shù)中必須調(diào)用在point_2d的公的公有成員函數(shù)有成員函數(shù)setpoint2實(shí)

10、現(xiàn)。實(shí)現(xiàn)。vpoint_3d類(lèi)的使用和普通類(lèi)完全一樣,用戶(hù)不用類(lèi)的使用和普通類(lèi)完全一樣,用戶(hù)不用去管這個(gè)類(lèi)是用繼承方式從另外一個(gè)類(lèi)擴(kuò)展而來(lái)去管這個(gè)類(lèi)是用繼承方式從另外一個(gè)類(lèi)擴(kuò)展而來(lái),還是完全直接定義的。,還是完全直接定義的。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 14int main()point_2d p1; point_3d p2; p1.setpoint2(1, 2); cout p1: ( p1.getx() , p1.gety() ) endl; p2.setpoint3(1, 2, 3); cout p2: ( p2.getx() , p2.gety() , p2.ge

11、tz() ) endl; return 0;P1: (1, 2)P2: (1, 2, 3)程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 15v單繼承的格式單繼承的格式v基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性 v派生類(lèi)對(duì)象的構(gòu)造、析構(gòu)與賦值操作派生類(lèi)對(duì)象的構(gòu)造、析構(gòu)與賦值操作 v重定義基類(lèi)的函數(shù)重定義基類(lèi)的函數(shù) v派生類(lèi)作為基類(lèi)派生類(lèi)作為基類(lèi) v將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 16v由于派生類(lèi)繼承了其基類(lèi)的成員,所以在由于派生類(lèi)繼承了其基類(lèi)的成員,所以在建立派生類(lèi)的實(shí)例對(duì)象時(shí),必須初始化基建

12、立派生類(lèi)的實(shí)例對(duì)象時(shí),必須初始化基類(lèi)繼承的數(shù)據(jù)成員。派生類(lèi)對(duì)象析構(gòu)時(shí),類(lèi)繼承的數(shù)據(jù)成員。派生類(lèi)對(duì)象析構(gòu)時(shí),也必須析構(gòu)基類(lèi)對(duì)象。也必須析構(gòu)基類(lèi)對(duì)象。v派生類(lèi)不繼承基類(lèi)的構(gòu)造函數(shù)、析構(gòu)函數(shù)派生類(lèi)不繼承基類(lèi)的構(gòu)造函數(shù)、析構(gòu)函數(shù)和賦值運(yùn)算符,但是派生類(lèi)的構(gòu)造函數(shù)、和賦值運(yùn)算符,但是派生類(lèi)的構(gòu)造函數(shù)、析構(gòu)函數(shù)和賦值運(yùn)算符能調(diào)用基類(lèi)的構(gòu)造析構(gòu)函數(shù)和賦值運(yùn)算符能調(diào)用基類(lèi)的構(gòu)造函數(shù)、析構(gòu)函數(shù)和賦值運(yùn)算符。函數(shù)、析構(gòu)函數(shù)和賦值運(yùn)算符。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 17v基類(lèi)成員的初始化由基類(lèi)的構(gòu)造函數(shù)完成?;?lèi)成員的初始化由基類(lèi)的構(gòu)造函數(shù)完成。派生類(lèi)的構(gòu)造函數(shù)調(diào)用基類(lèi)的構(gòu)造函數(shù)完成派生類(lèi)的

13、構(gòu)造函數(shù)調(diào)用基類(lèi)的構(gòu)造函數(shù)完成基類(lèi)成員的初始化?;?lèi)成員的初始化。v派生類(lèi)構(gòu)造函數(shù)可以隱式調(diào)用基類(lèi)缺省的構(gòu)派生類(lèi)構(gòu)造函數(shù)可以隱式調(diào)用基類(lèi)缺省的構(gòu)造函數(shù),也可以在派生類(lèi)的構(gòu)造函數(shù)的初始造函數(shù),也可以在派生類(lèi)的構(gòu)造函數(shù)的初始化列表顯式地調(diào)用基類(lèi)的構(gòu)造函數(shù)?;斜盹@式地調(diào)用基類(lèi)的構(gòu)造函數(shù)。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 18v派生類(lèi)構(gòu)造函數(shù)的格式:派生類(lèi)構(gòu)造函數(shù)的格式:派生類(lèi)構(gòu)造函數(shù)名(參數(shù)表):派生類(lèi)構(gòu)造函數(shù)名(參數(shù)表): 基類(lèi)構(gòu)造函數(shù)名(參數(shù)表)基類(lèi)構(gòu)造函數(shù)名(參數(shù)表) 。 v基類(lèi)構(gòu)造函數(shù)中的參數(shù)表通常來(lái)源于派生類(lèi)構(gòu)造函數(shù)基類(lèi)構(gòu)造函數(shù)中的參數(shù)表通常來(lái)源于派生類(lèi)構(gòu)造函數(shù)的參數(shù)表

14、,也可以用常數(shù)值。的參數(shù)表,也可以用常數(shù)值。 v如果構(gòu)造派生類(lèi)對(duì)象時(shí)調(diào)用的是基類(lèi)的缺省構(gòu)造函數(shù)如果構(gòu)造派生類(lèi)對(duì)象時(shí)調(diào)用的是基類(lèi)的缺省構(gòu)造函數(shù),則可以不要初始化列表。,則可以不要初始化列表。v如果派生類(lèi)新增的數(shù)據(jù)成員中含有對(duì)象成員,則在創(chuàng)如果派生類(lèi)新增的數(shù)據(jù)成員中含有對(duì)象成員,則在創(chuàng)建對(duì)象時(shí),先執(zhí)行基類(lèi)的構(gòu)造函數(shù),再執(zhí)行成員對(duì)象建對(duì)象時(shí),先執(zhí)行基類(lèi)的構(gòu)造函數(shù),再執(zhí)行成員對(duì)象的構(gòu)造函數(shù),最后執(zhí)行自己的構(gòu)造函數(shù)體。的構(gòu)造函數(shù),最后執(zhí)行自己的構(gòu)造函數(shù)體。 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 19v派生類(lèi)的析構(gòu)函數(shù)值析構(gòu)自己新增的數(shù)派生類(lèi)的析構(gòu)函數(shù)值析構(gòu)自己新增的數(shù)據(jù)成員,基類(lèi)成員的析構(gòu)

15、由基類(lèi)的析構(gòu)據(jù)成員,基類(lèi)成員的析構(gòu)由基類(lèi)的析構(gòu)函數(shù)析構(gòu)函數(shù)析構(gòu)v派生類(lèi)析構(gòu)函數(shù)會(huì)自動(dòng)調(diào)用基類(lèi)的析構(gòu)派生類(lèi)析構(gòu)函數(shù)會(huì)自動(dòng)調(diào)用基類(lèi)的析構(gòu)函數(shù)函數(shù)v派生類(lèi)對(duì)象析構(gòu)時(shí),先執(zhí)行派生類(lèi)的析派生類(lèi)對(duì)象析構(gòu)時(shí),先執(zhí)行派生類(lèi)的析構(gòu)函數(shù),再執(zhí)行基類(lèi)的析構(gòu)函數(shù)構(gòu)函數(shù),再執(zhí)行基類(lèi)的析構(gòu)函數(shù)程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 20v定義一個(gè)二維平面上的點(diǎn)類(lèi),并從它派定義一個(gè)二維平面上的點(diǎn)類(lèi),并從它派生出一個(gè)圓類(lèi)生出一個(gè)圓類(lèi)程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 21/ Definition of class Point#ifndef POINT2_H#define POINT2_Hclass

16、 Point public: Point( int = 0, int = 0 ); / default constructor Point(); / destructorprotected: / accessible by derived classes int x, y; / x and y coordinates of Point;#endif程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 22#include point2.h/ Constructor for class PointPoint:Point( int a, int b ) x = a; y = b; cout Poin

17、t constructor: x , y endl; / Destructor for class PointPoint:Point() cout Point destructor: x , y endl; 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 23#ifndef CIRCLE2_H#define CIRCLE2_H#include point2.hclass Circle : public Point public: / default constructor Circle( double r = 0.0, int x = 0, int y = 0 ); Circle(); p

18、rivate: double radius; ; #endif程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 24#include circle2.h / Constructor for Circle calls constructor for PointCircle:Circle( double r, int a, int b ) : Point( a, b ) / call base-class Constructor radius = r; / should validatecout Circle constructor: radius is radius x , y endl; /

19、 Destructor roi class CircleCircle:Circle() cout Circle destructor: radius is radius x , y endl; 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 25#include point2.h“#include circle2.h int main() / Show constructor and destructor calls for Point Point p( 11, 22 ); cout endl;Circle circle1( 4.5, 72, 29 );cout endl;Circle c

20、ircle2( 10, 5, 5 );cout endl;return 0; Point constructor: 11, 22 Point destructor: 11, 22 Point constructor: 72, 29 Circle constructor: radius is 4.5 72, 29Point constructor: 5, 5 Circle constructor: radius is 10 5, 5 Circle destructor: radius is 10 5, 5 Point destructor: 5, 5 Circle destructor: rad

21、ius is 4.5 72, 29 Point destructor: 72, 29 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 26v若基類(lèi)使用缺省或不帶參數(shù)的構(gòu)造函數(shù),則在若基類(lèi)使用缺省或不帶參數(shù)的構(gòu)造函數(shù),則在派生類(lèi)定義構(gòu)造函數(shù)是可略去:基類(lèi)構(gòu)造函數(shù)派生類(lèi)定義構(gòu)造函數(shù)是可略去:基類(lèi)構(gòu)造函數(shù)名(參數(shù)表)。此時(shí)若派生類(lèi)也不需要構(gòu)造函名(參數(shù)表)。此時(shí)若派生類(lèi)也不需要構(gòu)造函數(shù),則可不定義構(gòu)造函數(shù)。數(shù),則可不定義構(gòu)造函數(shù)。v當(dāng)基類(lèi)構(gòu)造函數(shù)需要參數(shù),而派生類(lèi)本身并不當(dāng)基類(lèi)構(gòu)造函數(shù)需要參數(shù),而派生類(lèi)本身并不需要構(gòu)造函數(shù)時(shí),派生類(lèi)還必須定義構(gòu)造函數(shù)需要構(gòu)造函數(shù)時(shí),派生類(lèi)還必須定義構(gòu)造函數(shù)。該函

22、數(shù)只是起了一個(gè)參數(shù)傳遞作用。該函數(shù)只是起了一個(gè)參數(shù)傳遞作用。v如果省略了派生類(lèi)的構(gòu)造函數(shù),那么就由派生如果省略了派生類(lèi)的構(gòu)造函數(shù),那么就由派生類(lèi)的默認(rèn)構(gòu)造函數(shù)調(diào)用基類(lèi)的默認(rèn)構(gòu)造函數(shù)。類(lèi)的默認(rèn)構(gòu)造函數(shù)調(diào)用基類(lèi)的默認(rèn)構(gòu)造函數(shù)。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 27v定義一個(gè)圖書(shū)館系統(tǒng)中的讀者類(lèi),每個(gè)定義一個(gè)圖書(shū)館系統(tǒng)中的讀者類(lèi),每個(gè)讀者的信息包括:卡號(hào)、姓名、單位、讀者的信息包括:卡號(hào)、姓名、單位、允許借書(shū)的數(shù)量以及已借書(shū)記錄。學(xué)生允許借書(shū)的數(shù)量以及已借書(shū)記錄。學(xué)生最多允許借最多允許借5本書(shū),教師最多允許借本書(shū),教師最多允許借10本書(shū)。本書(shū)。 程序設(shè)計(jì) cs.sjtu 2011.

23、9程序設(shè)計(jì) - 28v系統(tǒng)中有兩類(lèi)讀者:學(xué)生讀者和教師讀者系統(tǒng)中有兩類(lèi)讀者:學(xué)生讀者和教師讀者。v這兩類(lèi)讀者有一部分內(nèi)容是相同的:卡號(hào)這兩類(lèi)讀者有一部分內(nèi)容是相同的:卡號(hào)、姓名和單位。、姓名和單位。v可將兩類(lèi)讀者的共同部分內(nèi)容設(shè)計(jì)成一個(gè)可將兩類(lèi)讀者的共同部分內(nèi)容設(shè)計(jì)成一個(gè)基類(lèi)。基類(lèi)。v學(xué)生讀者和教師讀者從基類(lèi)派生,增加已學(xué)生讀者和教師讀者從基類(lèi)派生,增加已借書(shū)的數(shù)量以及已借書(shū)記錄兩個(gè)數(shù)據(jù)成員借書(shū)的數(shù)量以及已借書(shū)記錄兩個(gè)數(shù)據(jù)成員,并將允許借書(shū)的數(shù)量定義為整個(gè)類(lèi)共享,并將允許借書(shū)的數(shù)量定義為整個(gè)類(lèi)共享的常量的常量 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 29class readerin

24、t no;char name10;char dept20;public:reader(int n, char *nm, char *d) no = n; strcpy(name, nm); strcpy(dept, d); ;程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 30class readerTeacher :public readerenum MAX = 10; int borrowed;int recordMAX;public:readerTeacher(int n, char *nm, char *d):reader(n, nm, d) borrowed = 0;bool b

25、ookBorrow(int bookNo);bool bookReturn(int bookNo); void show(); /顯示已借書(shū)信息顯示已借書(shū)信息; 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 31class readerStudent :public reader enum MAX = 5;int borrowed;int recordMAX;public:readerStudent(int n, char *nm, char *d):reader(n, nm, d) borrowed = 0; bool bookBorrow(int bookNo);bool bookR

26、eturn(int bookNo); void show(); /顯示已借書(shū)信息顯示已借書(shū)信息; 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 32v單繼承的格式單繼承的格式v基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性 v派生類(lèi)對(duì)象的構(gòu)造、析構(gòu)與賦值操作派生類(lèi)對(duì)象的構(gòu)造、析構(gòu)與賦值操作 v重定義基類(lèi)的函數(shù)重定義基類(lèi)的函數(shù) v派生類(lèi)作為基類(lèi)派生類(lèi)作為基類(lèi) v將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 33v派生類(lèi)是基類(lèi)的擴(kuò)展,可以是保存的數(shù)據(jù)內(nèi)容的派生類(lèi)是基類(lèi)的擴(kuò)展,可以是保存的數(shù)據(jù)內(nèi)容的擴(kuò)展,也可以是功能

27、的擴(kuò)展。擴(kuò)展,也可以是功能的擴(kuò)展。v當(dāng)派生類(lèi)對(duì)基類(lèi)的某個(gè)功能進(jìn)行擴(kuò)展時(shí),他定義當(dāng)派生類(lèi)對(duì)基類(lèi)的某個(gè)功能進(jìn)行擴(kuò)展時(shí),他定義的成員函數(shù)名可能會(huì)和基類(lèi)的成員函數(shù)名重復(fù)。的成員函數(shù)名可能會(huì)和基類(lèi)的成員函數(shù)名重復(fù)。v如果只是函數(shù)名相同,而原型不同時(shí),系統(tǒng)認(rèn)為如果只是函數(shù)名相同,而原型不同時(shí),系統(tǒng)認(rèn)為派生類(lèi)中有兩個(gè)重載函數(shù)。如果原型完全相同,派生類(lèi)中有兩個(gè)重載函數(shù)。如果原型完全相同,則派生類(lèi)的函數(shù)會(huì)覆蓋基類(lèi)的函數(shù)。這稱(chēng)為重定則派生類(lèi)的函數(shù)會(huì)覆蓋基類(lèi)的函數(shù)。這稱(chēng)為重定義基類(lèi)的成員函數(shù)。義基類(lèi)的成員函數(shù)。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 34v 定義一個(gè)圓類(lèi)型,用于保存圓以及輸出定義一個(gè)圓類(lèi)

28、型,用于保存圓以及輸出圓的面積和周長(zhǎng)。在此類(lèi)型的基礎(chǔ)上派圓的面積和周長(zhǎng)。在此類(lèi)型的基礎(chǔ)上派生出一個(gè)球類(lèi)型,可以計(jì)算球的表面積生出一個(gè)球類(lèi)型,可以計(jì)算球的表面積和體積。和體積。 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 35v數(shù)據(jù)成員:圓的半徑數(shù)據(jù)成員:圓的半徑v成員函數(shù):由于需要提供圓的面積和周成員函數(shù):由于需要提供圓的面積和周長(zhǎng),需要提供兩個(gè)公有的成員函數(shù)。除長(zhǎng),需要提供兩個(gè)公有的成員函數(shù)。除了這些之外,還需要一個(gè)構(gòu)造函數(shù)了這些之外,還需要一個(gè)構(gòu)造函數(shù) 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 36class circle protected: double radius

29、;public:circle(double r = 0) radius = r;double getr() return radius;double area() return 3.14 * radius * radius; double circum() return 2 * 3.14 * radius; 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 37class ball:public circle public:ball(double r = 0):circle(r) double area() return 4 * 3.14 * radius * radius; double

30、volumn() return 4 * 3.14 * radius * radius * radius / 3; ;程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 38vBall類(lèi)沒(méi)有新增加數(shù)據(jù)成員,因而不需類(lèi)沒(méi)有新增加數(shù)據(jù)成員,因而不需要構(gòu)造函數(shù)。但基類(lèi)的構(gòu)造函數(shù)需要參要構(gòu)造函數(shù)。但基類(lèi)的構(gòu)造函數(shù)需要參數(shù),所以數(shù),所以ball類(lèi)必須寫(xiě)構(gòu)造函數(shù)類(lèi)必須寫(xiě)構(gòu)造函數(shù)vBall類(lèi)構(gòu)造函數(shù)的作用是為類(lèi)構(gòu)造函數(shù)的作用是為circle類(lèi)的構(gòu)類(lèi)的構(gòu)造函數(shù)傳遞參數(shù)造函數(shù)傳遞參數(shù)程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 39vBall類(lèi)包含了兩個(gè)原型完全一樣的類(lèi)包含了兩個(gè)原型完全一樣的area函數(shù)。

31、一個(gè)是自己定義的,一個(gè)是從函數(shù)。一個(gè)是自己定義的,一個(gè)是從circle類(lèi)繼承來(lái)的類(lèi)繼承來(lái)的v當(dāng)對(duì)當(dāng)對(duì)ball類(lèi)的對(duì)象調(diào)用類(lèi)的對(duì)象調(diào)用area函數(shù)時(shí),調(diào)函數(shù)時(shí),調(diào)用的是用的是ball類(lèi)自己定義的類(lèi)自己定義的area函數(shù)函數(shù)程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 40v派生類(lèi)中重新定義基類(lèi)的成員函數(shù)時(shí),派生類(lèi)中重新定義基類(lèi)的成員函數(shù)時(shí),它的功能往往是基類(lèi)功能的擴(kuò)展。為完它的功能往往是基類(lèi)功能的擴(kuò)展。為完成擴(kuò)展的工作,派生類(lèi)版本通常要調(diào)用成擴(kuò)展的工作,派生類(lèi)版本通常要調(diào)用基類(lèi)中的該函數(shù)版本?;?lèi)中的該函數(shù)版本。v引用基類(lèi)的同名函數(shù)必須使用作用域運(yùn)引用基類(lèi)的同名函數(shù)必須使用作用域運(yùn)算符,否

32、則會(huì)由于派生類(lèi)成員函數(shù)實(shí)際算符,否則會(huì)由于派生類(lèi)成員函數(shù)實(shí)際上調(diào)用了自身而引起無(wú)窮遞歸。這樣會(huì)上調(diào)用了自身而引起無(wú)窮遞歸。這樣會(huì)使系統(tǒng)用光內(nèi)存,是致命的運(yùn)行時(shí)錯(cuò)誤使系統(tǒng)用光內(nèi)存,是致命的運(yùn)行時(shí)錯(cuò)誤。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 41v在在circle類(lèi)的基礎(chǔ)上定義一個(gè)類(lèi)的基礎(chǔ)上定義一個(gè)cylinder類(lèi)??深?lèi)??梢杂?jì)算圓柱體的表面積和體積以計(jì)算圓柱體的表面積和體積 v設(shè)計(jì)考慮:設(shè)計(jì)考慮:存儲(chǔ)圓柱體可以在圓的基礎(chǔ)上增加一個(gè)高度。存儲(chǔ)圓柱體可以在圓的基礎(chǔ)上增加一個(gè)高度。圓柱體的表面積是上下兩個(gè)圓的面積加上它的圓柱體的表面積是上下兩個(gè)圓的面積加上它的側(cè)面積側(cè)面積圓柱體的體積是底

33、面積乘上高度。而求圓的面圓柱體的體積是底面積乘上高度。而求圓的面積的函數(shù)在積的函數(shù)在circle類(lèi)中已經(jīng)存在。類(lèi)中已經(jīng)存在。 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 42class cylinder:public circle double height;public:cylinder(double r = 0, double h = 0):circle(r) height = h;double geth() return height;double area() return 2 * circle:area() + circum() * height; double volumn

34、() return circle:area() * height ; ;程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 43int main()circle c(3); ball b(2); cylinder cy(1,2); cout circle: r= c.getr() endl; cout area= c.area() tcircum= c.circum() endl; cout ball: r= b.getr() endl; cout area= b.area() tvolumn= b.volumn() endl; cout cylinder: r= cy.getr() th =

35、 cy.geth() endl; cout area= cy.area() tvolumn= cy.volumn() endl; return 0;程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 44circle: r=3area=28.26 circum=18.84ball: r=2area=50.24 volumn=33.4933cylinder: r=1area=18.84 volumn=6.28程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 45v單繼承的格式單繼承的格式v基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性 v派生類(lèi)對(duì)象的構(gòu)造、析構(gòu)與賦值操作派生類(lèi)對(duì)象的構(gòu)

36、造、析構(gòu)與賦值操作 v重定義基類(lèi)的函數(shù)重定義基類(lèi)的函數(shù) v派生類(lèi)作為基類(lèi)派生類(lèi)作為基類(lèi) v將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 46v基類(lèi)本身可以是一個(gè)派生類(lèi),如:基類(lèi)本身可以是一個(gè)派生類(lèi),如:class base class d1:public base class d2:public d1 v每個(gè)派生類(lèi)繼承他的直接基類(lèi)的所有成員。每個(gè)派生類(lèi)繼承他的直接基類(lèi)的所有成員。v如果派生類(lèi)的基類(lèi)是一個(gè)派生類(lèi),則每個(gè)派生類(lèi)只負(fù)責(zé)如果派生類(lèi)的基類(lèi)是一個(gè)派生類(lèi),則每個(gè)派生類(lèi)只負(fù)責(zé)他的直接基類(lèi)的構(gòu)造,依次上溯。他的直接基類(lèi)的構(gòu)造,依

37、次上溯。v當(dāng)構(gòu)造當(dāng)構(gòu)造d2類(lèi)的對(duì)象時(shí),會(huì)先調(diào)用類(lèi)的對(duì)象時(shí),會(huì)先調(diào)用d1的構(gòu)造函數(shù),而的構(gòu)造函數(shù),而d1的構(gòu)造函數(shù)執(zhí)行時(shí)又會(huì)先調(diào)用的構(gòu)造函數(shù)執(zhí)行時(shí)又會(huì)先調(diào)用base的構(gòu)造函數(shù)。因此,的構(gòu)造函數(shù)。因此,構(gòu)造構(gòu)造d2類(lèi)的對(duì)象時(shí),最先初始化的是類(lèi)的對(duì)象時(shí),最先初始化的是base的數(shù)據(jù)成員,的數(shù)據(jù)成員,再初始化再初始化d1新增的成員,最后初始化新增的成員,最后初始化d2新增的成員。新增的成員。v析構(gòu)的過(guò)程正好相反。析構(gòu)的過(guò)程正好相反。 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 47#include using namespace std;class base int x; public: ba

38、se(int xx) x=xx; coutconstructing basen; base() coutdestructint basen; ;class derive1:public base int y;public:derive1(int xx, int yy): base(xx) y = yy; coutconstructing derive1n; derive1() coutdestructing derive1n; ;程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 48class derive2:public derive1 int z;public:derive2(int x

39、x, int yy, int zz):derive1(xx, yy) z = zz;coutconstructing derive2n; derive2() coutdestructing derive2n; ;main()derive2 op(1, 2, 3); return 0;constructing baseconstructing derive1constructing derive2 destructing derive2destructing derive1destructint base程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 49v單繼承的格式單繼承的格式v基類(lèi)成員

40、在派生類(lèi)中的訪問(wèn)特性基類(lèi)成員在派生類(lèi)中的訪問(wèn)特性 v派生類(lèi)對(duì)象的構(gòu)造、析構(gòu)與賦值操作派生類(lèi)對(duì)象的構(gòu)造、析構(gòu)與賦值操作 v重定義基類(lèi)的函數(shù)重定義基類(lèi)的函數(shù) v派生類(lèi)作為基類(lèi)派生類(lèi)作為基類(lèi) v將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象將派生類(lèi)對(duì)象隱式轉(zhuǎn)換為基類(lèi)對(duì)象 程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 50v將派生類(lèi)對(duì)象賦給基類(lèi)對(duì)象將派生類(lèi)對(duì)象賦給基類(lèi)對(duì)象v基類(lèi)指針指向派生類(lèi)對(duì)象基類(lèi)指針指向派生類(lèi)對(duì)象v基類(lèi)的對(duì)象引用派生類(lèi)的對(duì)象基類(lèi)的對(duì)象引用派生類(lèi)的對(duì)象程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 51v派生類(lèi)中的基類(lèi)部分賦給此基類(lèi)對(duì)象,派生派生類(lèi)中的基類(lèi)部分賦給此基類(lèi)對(duì)象,派生類(lèi)新增加的

41、成員就舍棄了。賦值后,基類(lèi)對(duì)類(lèi)新增加的成員就舍棄了。賦值后,基類(lèi)對(duì)象和派生類(lèi)對(duì)象再無(wú)任何關(guān)系。象和派生類(lèi)對(duì)象再無(wú)任何關(guān)系。 class base public: int a; ;class d1:public base public: int b; ; d1 d;d.a = 1; d.b = 2;base bb = d;cout bb.a; /輸出輸出1bb.a = 3;cout d.a; /輸出輸出1程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 52v盡管該指針指向的對(duì)象是一個(gè)派生類(lèi)對(duì)象,但由盡管該指針指向的對(duì)象是一個(gè)派生類(lèi)對(duì)象,但由于它本身是一個(gè)基類(lèi)的指針,它只能解釋基類(lèi)的于它本身是

42、一個(gè)基類(lèi)的指針,它只能解釋基類(lèi)的成員,而不能解釋派生類(lèi)新增的成員。因此,只成員,而不能解釋派生類(lèi)新增的成員。因此,只能訪問(wèn)派生類(lèi)中的基類(lèi)部分。能訪問(wèn)派生類(lèi)中的基類(lèi)部分。 v通過(guò)指針修改基類(lèi)對(duì)象時(shí),派生類(lèi)對(duì)象也被修改通過(guò)指針修改基類(lèi)對(duì)象時(shí),派生類(lèi)對(duì)象也被修改。d1 d;d.a = 1; d.b = 2;base *bp = &d;cout a; /輸出輸出1Bp-a = 3;cout d.a; /輸出輸出3程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 53v給派生類(lèi)中的基類(lèi)部分取個(gè)別名。給派生類(lèi)中的基類(lèi)部分取個(gè)別名。v基類(lèi)對(duì)象改變時(shí),派生類(lèi)對(duì)象也被修改?;?lèi)對(duì)象改變時(shí),派生類(lèi)對(duì)象也被修改。

43、d1 d;d.a = 1; d.b = 2;base &bb = d;cout bb.a; /輸出輸出1bb.a = 3;cout d.a; /輸出輸出3程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 54class Shape public: void printShapeName() cout“Shape”endl; ;class Point : public Shape public: void printShapeName() cout“Point”endl;class Circle : public Point public: void printShapeName() cout

44、“Circle”endl;class Cylinder : public Circle public: void printShapeName() cout“Cylinder”endl;實(shí)例程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 55int i;Point aPoint;Circle aCircle;Cylinder aCylinder;Shape shapes3= aPoint, aCircle, aCylinder;for (i=0;i3;i+) shapesi.printShapeName(); ShapeShapeShape程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) -

45、 56int i;Point aPoint;Circle aCircle;Cylinder aCylinder;Shape *pShape3= &aPoint, &aCircle, &aCylinder ;for (i=0;iprintShapeName(); ShapeShapeShape程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 57int i;Point aPoint;Circle aCircle;Cylinder aCylinder;Shape &shape1= aPoint;shape1.printShapeName(); shape程序設(shè)計(jì) cs.sjtu 2011.9程序

46、設(shè)計(jì) - 58v不能將基類(lèi)對(duì)象賦給派生類(lèi)對(duì)象,除非在基不能將基類(lèi)對(duì)象賦給派生類(lèi)對(duì)象,除非在基類(lèi)中定義了向派生類(lèi)的類(lèi)型轉(zhuǎn)換函數(shù)類(lèi)中定義了向派生類(lèi)的類(lèi)型轉(zhuǎn)換函數(shù)v不能將基類(lèi)對(duì)象地址賦給指向派生類(lèi)對(duì)象的不能將基類(lèi)對(duì)象地址賦給指向派生類(lèi)對(duì)象的指針指針v也不能將指向基類(lèi)對(duì)象的指針賦給指向派生也不能將指向基類(lèi)對(duì)象的指針賦給指向派生類(lèi)對(duì)象的指針。如果程序員能確保這個(gè)基類(lèi)類(lèi)對(duì)象的指針。如果程序員能確保這個(gè)基類(lèi)指針指向的是一個(gè)派生類(lèi)的對(duì)象,則可以用指針指向的是一個(gè)派生類(lèi)的對(duì)象,則可以用reinterpret_cast類(lèi)型的強(qiáng)制類(lèi)型轉(zhuǎn)換。表示程類(lèi)型的強(qiáng)制類(lèi)型轉(zhuǎn)換。表示程序員知道這個(gè)風(fēng)險(xiǎn)序員知道這個(gè)風(fēng)險(xiǎn)程序設(shè)計(jì) c

47、s.sjtu 2011.9程序設(shè)計(jì) - 59v組合組合 v繼承繼承 v虛函數(shù)與多態(tài)性虛函數(shù)與多態(tài)性v純虛函數(shù)與抽象類(lèi)純虛函數(shù)與抽象類(lèi) v多繼承多繼承 v面向?qū)ο笤O(shè)計(jì)范例面向?qū)ο笤O(shè)計(jì)范例程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 60v多態(tài)性多態(tài)性v虛函數(shù)虛函數(shù)v虛析構(gòu)函數(shù)虛析構(gòu)函數(shù)程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 61v多態(tài)性:不同對(duì)象收到相同的消息時(shí)產(chǎn)多態(tài)性:不同對(duì)象收到相同的消息時(shí)產(chǎn)生不同的動(dòng)作。生不同的動(dòng)作。v多態(tài)性的作用:便于系統(tǒng)功能的擴(kuò)展多態(tài)性的作用:便于系統(tǒng)功能的擴(kuò)展程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 62v靜態(tài)聯(lián)編:編譯時(shí)已決定用哪一個(gè)函

48、數(shù)靜態(tài)聯(lián)編:編譯時(shí)已決定用哪一個(gè)函數(shù)實(shí)現(xiàn)某一動(dòng)作。實(shí)現(xiàn)某一動(dòng)作。v動(dòng)態(tài)聯(lián)編:直到運(yùn)行時(shí)才決定用哪一個(gè)動(dòng)態(tài)聯(lián)編:直到運(yùn)行時(shí)才決定用哪一個(gè)函數(shù)來(lái)實(shí)現(xiàn)動(dòng)作函數(shù)來(lái)實(shí)現(xiàn)動(dòng)作程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 63v函數(shù)重載:用同一名字實(shí)現(xiàn)訪問(wèn)一組相函數(shù)重載:用同一名字實(shí)現(xiàn)訪問(wèn)一組相關(guān)的函數(shù)關(guān)的函數(shù)v運(yùn)算符重載運(yùn)算符重載v重載函數(shù)是通過(guò)重載函數(shù)是通過(guò)“名字壓延名字壓延”方法來(lái)實(shí)方法來(lái)實(shí)現(xiàn)。即在編譯時(shí)將函數(shù)名和參數(shù)結(jié)合起現(xiàn)。即在編譯時(shí)將函數(shù)名和參數(shù)結(jié)合起來(lái)創(chuàng)造一個(gè)新的函數(shù)名,用新的名字替來(lái)創(chuàng)造一個(gè)新的函數(shù)名,用新的名字替換原有名字。換原有名字。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì)

49、- 64v運(yùn)行時(shí)多態(tài)性是指必須等到運(yùn)行時(shí)多態(tài)性是指必須等到程序動(dòng)態(tài)運(yùn)行程序動(dòng)態(tài)運(yùn)行時(shí)才可確定的多態(tài)性,時(shí)才可確定的多態(tài)性,主要通過(guò)主要通過(guò)繼承繼承結(jié)合結(jié)合動(dòng)態(tài)綁定動(dòng)態(tài)綁定獲得。這與類(lèi)的繼承密切相關(guān)。獲得。這與類(lèi)的繼承密切相關(guān)。因?yàn)榇嬖陬?lèi)型的兼容性,所以有些函數(shù)只因?yàn)榇嬖陬?lèi)型的兼容性,所以有些函數(shù)只有在運(yùn)行時(shí)才能確定是調(diào)用父類(lèi)的還是子有在運(yùn)行時(shí)才能確定是調(diào)用父類(lèi)的還是子類(lèi)的函數(shù)。在類(lèi)的函數(shù)。在C+C+中,使用中,使用虛函數(shù)虛函數(shù)(Virtual FunctionsVirtual Functions)來(lái)實(shí)現(xiàn)。)來(lái)實(shí)現(xiàn)。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 65v多態(tài)性多態(tài)性v虛函數(shù)虛

50、函數(shù)v虛析構(gòu)函數(shù)虛析構(gòu)函數(shù)程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 66v虛函數(shù)提供動(dòng)態(tài)重載方式,允許函數(shù)調(diào)用與函數(shù)虛函數(shù)提供動(dòng)態(tài)重載方式,允許函數(shù)調(diào)用與函數(shù)體之間的聯(lián)系在運(yùn)行時(shí)才建立。體之間的聯(lián)系在運(yùn)行時(shí)才建立。v虛函數(shù)的定義:在基類(lèi)中用關(guān)鍵詞虛函數(shù)的定義:在基類(lèi)中用關(guān)鍵詞virtual說(shuō)明,說(shuō)明,并在派生類(lèi)中重新定義的函數(shù)稱(chēng)為虛函數(shù)。在派并在派生類(lèi)中重新定義的函數(shù)稱(chēng)為虛函數(shù)。在派生類(lèi)中重新定義時(shí),其函數(shù)原型,包括返回類(lèi)型生類(lèi)中重新定義時(shí),其函數(shù)原型,包括返回類(lèi)型、函數(shù)名、參數(shù)個(gè)數(shù)與參數(shù)類(lèi)型的順序都必須與、函數(shù)名、參數(shù)個(gè)數(shù)與參數(shù)類(lèi)型的順序都必須與基類(lèi)中的原型完全相同?;?lèi)中的原型完

51、全相同。v當(dāng)把一個(gè)函數(shù)定義為虛函數(shù)時(shí),等于告訴編譯器當(dāng)把一個(gè)函數(shù)定義為虛函數(shù)時(shí),等于告訴編譯器,這個(gè)成員函數(shù)在派生類(lèi)中可能有不同的實(shí)現(xiàn)。,這個(gè)成員函數(shù)在派生類(lèi)中可能有不同的實(shí)現(xiàn)。必須在執(zhí)行時(shí)根據(jù)傳遞的參數(shù)來(lái)決定調(diào)用哪一個(gè)必須在執(zhí)行時(shí)根據(jù)傳遞的參數(shù)來(lái)決定調(diào)用哪一個(gè)函數(shù)函數(shù)程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 67v虛函數(shù)是與基類(lèi)指針指向派生類(lèi)對(duì)象,或基類(lèi)虛函數(shù)是與基類(lèi)指針指向派生類(lèi)對(duì)象,或基類(lèi)對(duì)象引用派生類(lèi)對(duì)象結(jié)合起來(lái)實(shí)現(xiàn)多態(tài)性。對(duì)象引用派生類(lèi)對(duì)象結(jié)合起來(lái)實(shí)現(xiàn)多態(tài)性。v當(dāng)基類(lèi)指針指向派生類(lèi)對(duì)象或基類(lèi)對(duì)象引用派當(dāng)基類(lèi)指針指向派生類(lèi)對(duì)象或基類(lèi)對(duì)象引用派生類(lèi)對(duì)象時(shí),對(duì)基類(lèi)指針或?qū)ο笳{(diào)用基

52、類(lèi)的虛生類(lèi)對(duì)象時(shí),對(duì)基類(lèi)指針或?qū)ο笳{(diào)用基類(lèi)的虛函數(shù),系統(tǒng)會(huì)到相應(yīng)的派生類(lèi)中尋找此虛函數(shù)函數(shù),系統(tǒng)會(huì)到相應(yīng)的派生類(lèi)中尋找此虛函數(shù)的重定義。如找到,則執(zhí)行派生類(lèi)中的函數(shù)。的重定義。如找到,則執(zhí)行派生類(lèi)中的函數(shù)。如沒(méi)有找到,則執(zhí)行基類(lèi)的虛函數(shù)。如沒(méi)有找到,則執(zhí)行基類(lèi)的虛函數(shù)。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 68class Shape public:virtual void printShapeName() cout“Shape”endl; ;class Point:public Shape public:virtual void printShapeName() cout“Poi

53、nt”endl;class Circle:public Point public: virtual void printShapeName() cout“Circle”endl;class Cylinder:public Circle public: virtual void printShapeName() cout“Cylinder”endl;程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 69int i;Point aPoint;Circle aCircle;Cylinder aCylinder;Shape shapes3= aPoint, aCircle, aCylinder;fo

54、r (i=0;i3;i+) shapesi.printShapeName(); ShapeShapeShape程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 70int i;Point aPoint;Circle aCircle;Cylinder aCylinder;Shape *pShape3= &aPoint, &aCircle, &aCylinder ;for (i=0;iprintShapeName(); PointCircleCylinder程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 71int i;Point aPoint;Circle aCircle;Cylinder

55、 aCylinder;/Shape *pShape3= &aPoint, &aCircle, &aCylinder;Shape &shape1= aPoint;/for (i=0;iprintShapeName(); shape1.printShapeName(); Point程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 72v在派生類(lèi)中重新定義虛函數(shù)時(shí),它的原型必在派生類(lèi)中重新定義虛函數(shù)時(shí),它的原型必須與基類(lèi)中的虛函數(shù)完全相同。否則編譯器須與基類(lèi)中的虛函數(shù)完全相同。否則編譯器會(huì)把它認(rèn)為是重載函數(shù),而不是虛函數(shù)的重會(huì)把它認(rèn)為是重載函數(shù),而不是虛函數(shù)的重定義。定義。v派生類(lèi)在對(duì)基類(lèi)的虛函數(shù)

56、重定義時(shí),關(guān)鍵字派生類(lèi)在對(duì)基類(lèi)的虛函數(shù)重定義時(shí),關(guān)鍵字virtual可以寫(xiě)也可以不寫(xiě)。不管可以寫(xiě)也可以不寫(xiě)。不管virtual寫(xiě)或者寫(xiě)或者不寫(xiě),該函數(shù)都被認(rèn)為是虛函數(shù)。但最好是不寫(xiě),該函數(shù)都被認(rèn)為是虛函數(shù)。但最好是在重定義時(shí)寫(xiě)上在重定義時(shí)寫(xiě)上virtual。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 73v正方形是一類(lèi)特殊的矩形,因此,可以正方形是一類(lèi)特殊的矩形,因此,可以從從rectangle類(lèi)派生一個(gè)類(lèi)派生一個(gè)square類(lèi)。在這類(lèi)。在這兩個(gè)類(lèi)中,都有一個(gè)顯示形狀的函數(shù)。兩個(gè)類(lèi)中,都有一個(gè)顯示形狀的函數(shù)。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 74class recta

57、ngle int w, h;public: rectangle(int ww, int hh): w(ww), h(hh) virtual void display() cout “this is a rectanglen”;class square:public rectangle public: square(int ss): rectangle(ss, ss) void display() /虛函數(shù)虛函數(shù) cout “this is a squaren”;程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 75v多態(tài)性多態(tài)性v虛函數(shù)虛函數(shù)v虛析構(gòu)函數(shù)虛析構(gòu)函數(shù)程序設(shè)計(jì) cs.sjtu 2

58、011.9程序設(shè)計(jì) - 76v構(gòu)造函數(shù)不能是虛函數(shù),但析構(gòu)函數(shù)可以是構(gòu)造函數(shù)不能是虛函數(shù),但析構(gòu)函數(shù)可以是虛函數(shù),而且最好是虛函數(shù)虛函數(shù),而且最好是虛函數(shù) v如果派生類(lèi)新增加的數(shù)據(jù)成員中含有指針,如果派生類(lèi)新增加的數(shù)據(jù)成員中含有指針,指向動(dòng)態(tài)申請(qǐng)的內(nèi)存,那么派生類(lèi)必須定義指向動(dòng)態(tài)申請(qǐng)的內(nèi)存,那么派生類(lèi)必須定義析構(gòu)函數(shù)釋放這部分空間。但如果派生類(lèi)的析構(gòu)函數(shù)釋放這部分空間。但如果派生類(lèi)的對(duì)象是通過(guò)基類(lèi)的指針操作的,則對(duì)象是通過(guò)基類(lèi)的指針操作的,則delete基基類(lèi)指針指向的對(duì)象就會(huì)造成內(nèi)存泄漏。類(lèi)指針指向的對(duì)象就會(huì)造成內(nèi)存泄漏。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 77v將基類(lèi)的析構(gòu)

59、函數(shù)定義為虛函數(shù)。將基類(lèi)的析構(gòu)函數(shù)定義為虛函數(shù)。v當(dāng)析構(gòu)基類(lèi)指向的派生類(lèi)的對(duì)象時(shí),找當(dāng)析構(gòu)基類(lèi)指向的派生類(lèi)的對(duì)象時(shí),找到基類(lèi)的析構(gòu)函數(shù)。由于基類(lèi)的析構(gòu)函到基類(lèi)的析構(gòu)函數(shù)。由于基類(lèi)的析構(gòu)函數(shù)是虛函數(shù),又會(huì)找到派生類(lèi)的析構(gòu)函數(shù)是虛函數(shù),又會(huì)找到派生類(lèi)的析構(gòu)函數(shù),執(zhí)行派生類(lèi)的析構(gòu)函數(shù)。數(shù),執(zhí)行派生類(lèi)的析構(gòu)函數(shù)。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 78v和其他的虛函數(shù)一樣,析構(gòu)函數(shù)的虛函和其他的虛函數(shù)一樣,析構(gòu)函數(shù)的虛函數(shù)的性質(zhì)將被繼承。數(shù)的性質(zhì)將被繼承。v如果繼承層次樹(shù)中的根類(lèi)的析構(gòu)函數(shù)是如果繼承層次樹(shù)中的根類(lèi)的析構(gòu)函數(shù)是虛函數(shù)的話,所有派生類(lèi)的析構(gòu)函數(shù)都虛函數(shù)的話,所有派生類(lèi)的析構(gòu)

60、函數(shù)都將是虛函數(shù)。將是虛函數(shù)。程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 79v組合組合 v繼承繼承 v虛函數(shù)與多態(tài)性虛函數(shù)與多態(tài)性v純虛函數(shù)與抽象類(lèi)純虛函數(shù)與抽象類(lèi) v多繼承多繼承 v面向?qū)ο笤O(shè)計(jì)范例面向?qū)ο笤O(shè)計(jì)范例程序設(shè)計(jì) cs.sjtu 2011.9程序設(shè)計(jì) - 80v純虛函數(shù):是一個(gè)在基類(lèi)中說(shuō)明的虛函純虛函數(shù):是一個(gè)在基類(lèi)中說(shuō)明的虛函數(shù),它在該基類(lèi)中沒(méi)有定義,但要在它數(shù),它在該基類(lèi)中沒(méi)有定義,但要在它的派生類(lèi)里定義自己的版本,或重新說(shuō)的派生類(lèi)里定義自己的版本,或重新說(shuō)明為純虛函數(shù)明為純虛函數(shù)v純虛函數(shù)的一般形式純虛函數(shù)的一般形式 virtual 類(lèi)型類(lèi)型 函數(shù)名(參數(shù)表)函數(shù)名

溫馨提示

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

評(píng)論

0/150

提交評(píng)論