第六章面向?qū)ο蟪绦蛟O(shè)計基礎(chǔ)_第1頁
第六章面向?qū)ο蟪绦蛟O(shè)計基礎(chǔ)_第2頁
第六章面向?qū)ο蟪绦蛟O(shè)計基礎(chǔ)_第3頁
第六章面向?qū)ο蟪绦蛟O(shè)計基礎(chǔ)_第4頁
第六章面向?qū)ο蟪绦蛟O(shè)計基礎(chǔ)_第5頁
已閱讀5頁,還剩51頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第六章第六章 面向?qū)ο蟪绦蛟O(shè)計基礎(chǔ)面向?qū)ο蟪绦蛟O(shè)計基礎(chǔ)6 6.1 面向?qū)ο蟪绦蛟O(shè)計概述面向?qū)ο蟪绦蛟O(shè)計概述 6 6.2 結(jié)構(gòu)結(jié)構(gòu) 6.3 類和對象類和對象 6.4 繼承和派生繼承和派生 6.5多態(tài)性多態(tài)性 6.6 程序舉例程序舉例6.1 6.1 面向?qū)ο蟪绦蛟O(shè)計(面向?qū)ο蟪绦蛟O(shè)計(OOPOOP)概述)概述基本概念基本概念 Object Oriented Programming 對象:現(xiàn)實世界的實體,每個對象都有所屬的類對象:現(xiàn)實世界的實體,每個對象都有所屬的類 類:類: 對一組對象共同具有的屬性和行為的抽象,對一組對象共同具有的屬性和行為的抽象, 具有封裝和隱藏性、還具有繼承性。具有封裝和隱藏

2、性、還具有繼承性。 消息:向某對象請求服務(wù)的一種表達方式,是對消息:向某對象請求服務(wù)的一種表達方式,是對 象與外界、對象與其它對象之間聯(lián)系的工具象與外界、對象與其它對象之間聯(lián)系的工具 方法:對某對象接受消息后所采取的操作的描述。方法:對某對象接受消息后所采取的操作的描述。 特點特點封裝性封裝性繼承性繼承性多態(tài)性多態(tài)性C+C+中,通過類和對象實現(xiàn)對數(shù)據(jù)的封裝,使得程序的修改維中,通過類和對象實現(xiàn)對數(shù)據(jù)的封裝,使得程序的修改維護更方便。是護更方便。是OOPOOP的基礎(chǔ)的基礎(chǔ)。連接類與類的層次模型,利用現(xiàn)有類派生出新類的過程稱為類連接類與類的層次模型,利用現(xiàn)有類派生出新類的過程稱為類繼承繼承, ,支

3、持代碼重用、提供了無限重復(fù)利用程序資源的途徑、支持代碼重用、提供了無限重復(fù)利用程序資源的途徑、節(jié)省程序開發(fā)的時間和資源,是節(jié)省程序開發(fā)的時間和資源,是OOPOOP的關(guān)鍵。的關(guān)鍵。發(fā)出同樣的消息被不同類型的對象接收時導(dǎo)致完全不同的行發(fā)出同樣的消息被不同類型的對象接收時導(dǎo)致完全不同的行為為, ,是是OOPOOP的重要補充的重要補充說明結(jié)說明結(jié)構(gòu)類型構(gòu)類型的關(guān)鍵字的關(guān)鍵字 6.2 6.2 結(jié)構(gòu)結(jié)構(gòu)C+C+中的類從中的類從C C語言中的結(jié)構(gòu)概念演變而來語言中的結(jié)構(gòu)概念演變而來 結(jié)構(gòu)類型說明形式結(jié)構(gòu)類型說明形式struct 結(jié)構(gòu)類型標(biāo)識符結(jié)構(gòu)類型標(biāo)識符 結(jié)構(gòu)成員結(jié)構(gòu)成員1;1; 結(jié)構(gòu)成員結(jié)構(gòu)成員2;2;

4、結(jié)構(gòu)成員結(jié)構(gòu)成員n;n;類型可任意類型可任意(不能為該結(jié)構(gòu)自身)(不能為該結(jié)構(gòu)自身)struct date int month; int day; int year; struct man char name15; char sex; int age; date birthday;如,說明一個結(jié)構(gòu)類型如,說明一個結(jié)構(gòu)類型datedate,含三個整型數(shù)據(jù)成員,含三個整型數(shù)據(jù)成員在此基礎(chǔ)上,又在此基礎(chǔ)上,又可說明另一個結(jié)可說明另一個結(jié)構(gòu)類型構(gòu)類型manmanbirthdayNamesexagemonthdayyear struct man結(jié)構(gòu)類型結(jié)構(gòu)變量定義結(jié)構(gòu)變量定義先說明結(jié)構(gòu)類型再定義結(jié)構(gòu)變量

5、先說明結(jié)構(gòu)類型再定義結(jié)構(gòu)變量在說明結(jié)構(gòu)數(shù)據(jù)類型的同時定義結(jié)構(gòu)變量在說明結(jié)構(gòu)數(shù)據(jù)類型的同時定義結(jié)構(gòu)變量省略結(jié)構(gòu)標(biāo)識符直接定義結(jié)構(gòu)類型變量省略結(jié)構(gòu)標(biāo)識符直接定義結(jié)構(gòu)類型變量struct man man1, man2;struct man char name15;char sex;int age; struct date birthday; man1, man2;struct char name15;char sex;int age; struct date birthday; man1, man2;無類型名變量無類型名變量結(jié)構(gòu)變量的引用結(jié)構(gòu)變量的引用形式:形式: 結(jié)構(gòu)變量名結(jié)構(gòu)變量名. .成員名成

6、員名( (* *指向結(jié)構(gòu)的指針指向結(jié)構(gòu)的指針).).成員名成員名 指向結(jié)構(gòu)的指針指向結(jié)構(gòu)的指針-成員名成員名或或或或通過指向結(jié)構(gòu)的指針引用結(jié)構(gòu)變量成員通過指向結(jié)構(gòu)的指針引用結(jié)構(gòu)變量成員成員訪問運算符成員訪問運算符優(yōu)先級最高的優(yōu)先級最高的四個運算符之一四個運算符之一 括號不能少括號不能少如,假設(shè)有定義如,假設(shè)有定義man m,*p=&m; strcpy (, Fang Min);p-birthday.month = 8; 則可如下引用結(jié)構(gòu)成員則可如下引用結(jié)構(gòu)成員6.3 6.3 類和對象類和對象引例引例定義一有關(guān)職工工資信息的結(jié)構(gòu)類型定義一有關(guān)職工工資信息的結(jié)構(gòu)類型,對某職工的該類信息

7、對某職工的該類信息進行處理。職工信息包括姓名、基本工資、崗位工資和職務(wù)工資;進行處理。職工信息包括姓名、基本工資、崗位工資和職務(wù)工資;對該類信息的處理包括輸入、輸出和求總收入情況。對該類信息的處理包括輸入、輸出和求總收入情況。 #include iostream.hstruct stuffchar name10; double jw,gw,zw;s ; void print( ):s.jws.gws.zw;double salary( )double sum=0; sum=sum+s.jw+s.gw+s.zw; return sum;

8、void main()input( ); print( ); coutsalary( );結(jié)構(gòu)化的方法結(jié)構(gòu)化的方法結(jié)構(gòu)化程序的框架結(jié)構(gòu)化程序的框架結(jié)構(gòu)化程序結(jié)構(gòu)化程序#include iostream.hclass stuffprivate: char name10; double jw,gw,zw;public:void print( )coutname:jwtgwtzwnamejwgwzw; double salary( )double sum=0; sum=sum+jw+gw+zw; return sum;void main()stuff s; s.input( ); s.print(

9、); couts.salary( );以面向?qū)ο蟮姆绞綄崿F(xiàn)以面向?qū)ο蟮姆绞綄崿F(xiàn)6.3.1 6.3.1 類的定義類的定義類是一種復(fù)雜的數(shù)據(jù)類型,它是將不同類型的類是一種復(fù)雜的數(shù)據(jù)類型,它是將不同類型的數(shù)據(jù)和與這些數(shù)據(jù)相關(guān)的運算封裝在一起的集合體,數(shù)據(jù)和與這些數(shù)據(jù)相關(guān)的運算封裝在一起的集合體,定義格式:定義格式:class 類名類名public: ; private: ; protected: ;; 說明:說明:定義包括說明部分和實現(xiàn)部分。若成員函數(shù)在說明部分定義包括說明部分和實現(xiàn)部分。若成員函數(shù)在說明部分已定義,則實現(xiàn)部分可省略;若成員函數(shù)在類體外實現(xiàn),已定義,則實現(xiàn)部分可省略;若成員函數(shù)在類體

10、外實現(xiàn),需用類名和作用域運算符(需用類名和作用域運算符(:)標(biāo)識所屬類。)標(biāo)識所屬類。訪問權(quán)限修飾符:訪問權(quán)限修飾符:public(公有)、(公有)、private(私有(私有 )和)和 protected(保護)(保護) 缺省時為缺省時為private。公有成員通常為成員函數(shù),可在程序中引用,私有成員公有成員通常為成員函數(shù),可在程序中引用,私有成員通常是數(shù)據(jù)成員,只有成員函數(shù)或友元函數(shù)才可引用。通常是數(shù)據(jù)成員,只有成員函數(shù)或友元函數(shù)才可引用。類體中不允許對數(shù)據(jù)成員初始化。類體中不允許對數(shù)據(jù)成員初始化。class Bprivate: int year=2002, month=10, day=1

11、2;錯錯 例例6-1:定義一個定義一個CircleCircle類類( (圓類圓類) ),包括如下的一些數(shù)據(jù)成員,包括如下的一些數(shù)據(jù)成員 和成員函數(shù)和成員函數(shù). .數(shù)據(jù)成員數(shù)據(jù)成員成員函數(shù)成員函數(shù)名稱名稱含義含義名稱名稱功能功能x圓心坐標(biāo)圓心坐標(biāo)x值值set設(shè)置數(shù)據(jù)成員值設(shè)置數(shù)據(jù)成員值y圓心坐標(biāo)圓心坐標(biāo)y值值print輸出數(shù)據(jù)成員值輸出數(shù)據(jù)成員值r圓半徑圓半徑 area 求圓的面積求圓的面積lenth求圓的周長求圓的周長class Circleprivate: double x,y,r; public: void print( ); void set(double x1,double y1,do

12、uble r1); double area( ) return (3.14*r*r); double lenth() return(2*3.14*r);void Circle:print()cout圓心圓心:(x,y)endl; cout半徑半徑:r-成員名成員名類成員的訪問方式類成員的訪問方式類內(nèi)類內(nèi): (成員函數(shù)訪問數(shù)據(jù)成員成員函數(shù)訪問數(shù)據(jù)成員)直接訪問類成員直接訪問類成員類外類外: (外部程序訪問類的成員函數(shù)外部程序訪問類的成員函數(shù))訪問方式同結(jié)構(gòu)成員訪問方式同結(jié)構(gòu)成員,具體如下具體如下:例例6-2編制主函數(shù),通過例編制主函數(shù),通過例6-1中定義的中定義的Circle類,對圓心在原點,類

13、,對圓心在原點,半徑為半徑為2的圓和圓心在點(的圓和圓心在點(1,1)上,半徑為)上,半徑為4的圓進行測試。的圓進行測試。 void main()Cirlce p1,*p2; p1.set(0,0,1); p1.print( ); coutp1.areatp1.lenthset(1,1,4); p2-print( ); coutareatlenthendl;6.3.3 6.3.3 對象的初始化對象的初始化1.1.構(gòu)造函數(shù)和析構(gòu)函數(shù)構(gòu)造函數(shù)和析構(gòu)函數(shù) 例例6-3 6-3 看例看例6-26-2的另一種實現(xiàn)的另一種實現(xiàn)class Circleprivate: double x,y,r; public

14、: void print( ); Circle(double x1,double y1,double r1); double area( ) return (3.14*r*r); double lenth() return(2*3.14*r);Circle:Circle(double x1,double y1,double r1) x=x1; y=y1; r=r1;/其它函數(shù)實現(xiàn)略其它函數(shù)實現(xiàn)略void main() Circle p (0,0,2); p.print(); 1.定義的同時定義的同時初始化對象初始化對象2.省略對賦初省略對賦初值成員函數(shù)值成員函數(shù)的額外調(diào)用的額外調(diào)用構(gòu)造函數(shù)特點

15、構(gòu)造函數(shù)特點析構(gòu)函數(shù)特點:析構(gòu)函數(shù)特點:若一個對象被定義在函數(shù)體內(nèi),則當(dāng)該函數(shù)結(jié)束時,若一個對象被定義在函數(shù)體內(nèi),則當(dāng)該函數(shù)結(jié)束時, 該對象的析構(gòu)函數(shù)被自動調(diào)用。該對象的析構(gòu)函數(shù)被自動調(diào)用。當(dāng)一個對象是使用當(dāng)一個對象是使用newnew運算符被動態(tài)創(chuàng)建的,在使用運算符被動態(tài)創(chuàng)建的,在使用deletedelete釋放時,析構(gòu)函數(shù)將會被自動調(diào)用釋放時,析構(gòu)函數(shù)將會被自動調(diào)用是成員函數(shù),可寫在類體內(nèi),亦可寫在類體外。是成員函數(shù),可寫在類體內(nèi),亦可寫在類體外。函數(shù)名同類名,不能指定函數(shù)類型,可以帶參數(shù)。函數(shù)名同類名,不能指定函數(shù)類型,可以帶參數(shù)??芍剌d,即可定義多個參數(shù)個數(shù)不同的函數(shù)??芍剌d,即可定義多

16、個參數(shù)個數(shù)不同的函數(shù)。在創(chuàng)建對象時由系統(tǒng)自動調(diào)用,程序中不能直接調(diào)用在創(chuàng)建對象時由系統(tǒng)自動調(diào)用,程序中不能直接調(diào)用。是成員函數(shù),可寫在類體內(nèi),亦可寫在類體外。是成員函數(shù),可寫在類體內(nèi),亦可寫在類體外。函數(shù)名同類名,前面多個字符函數(shù)名同類名,前面多個字符“” ,不指定類型,無參。,不指定類型,無參。不可重載,即一個類只能定義一個析構(gòu)函數(shù)。不可重載,即一個類只能定義一個析構(gòu)函數(shù)??杀徽{(diào)用,也可由系統(tǒng)調(diào)用。系統(tǒng)自動調(diào)用情況如下:可被調(diào)用,也可由系統(tǒng)調(diào)用。系統(tǒng)自動調(diào)用情況如下:2.2.缺省構(gòu)造函數(shù)和缺省析構(gòu)函數(shù)缺省構(gòu)造函數(shù)和缺省析構(gòu)函數(shù)形式:形式:說明:說明:若若沒有定義任何構(gòu)造函數(shù)沒有定義任何構(gòu)造函

17、數(shù),系統(tǒng)會自動生成上述無參的缺省,系統(tǒng)會自動生成上述無參的缺省構(gòu)造函數(shù)及析構(gòu)函數(shù)構(gòu)造函數(shù)及析構(gòu)函數(shù)若定義一個若定義一個靜態(tài)靜態(tài)對象而沒有指明初始化時,編譯器會按缺省對象而沒有指明初始化時,編譯器會按缺省構(gòu)造函數(shù)對對象的所有數(shù)據(jù)成員都初始化為或空。構(gòu)造函數(shù)對對象的所有數(shù)據(jù)成員都初始化為或空。 :() :( ) 例例6.3 6.3 定義一個定義一個Circle1Circle1類,具有求一個圓的面類,具有求一個圓的面積、求兩個圓的面積之和,以及輸出面積等功能積、求兩個圓的面積之和,以及輸出面積等功能 。#include iostream.hclass Circle1private: double x

18、,y,r,s; public: void print()cout圓心圓心:(x,y)endl; cout半徑半徑:rendl; Circle1() Circle1(double x1,double y1,double r1) x=x1; y=y1; r=r1; void addarea(Circle1 p1,Circle1 p2) s=3.14*(p1.r*p1.r)+3.14*(p2.r*p2.r); void disp() cout面積面積:sendl;void main() Circle1 p1(0,0,2),p2(1,1,4),p3; p1.print(); p2.print(); p

19、3.addarea(p1,p2); p3.disp();可缺省嗎?驗證一下可缺省嗎?驗證一下初始化了嗎初始化了嗎#include #include class countint num; public: count(); count(); void process(); ; count:count() num=0;count:count() cout字符個數(shù):字符個數(shù):numendl; void count:process() while(cin.get()!=n) num+; coutendl; void main()count c; cout輸入一個句子:輸入一個句子: ; ce

20、ss(); 例例6.4 6.4 析構(gòu)函數(shù)示例析構(gòu)函數(shù)示例析構(gòu)函數(shù)中輸出處理結(jié)析構(gòu)函數(shù)中輸出處理結(jié)果果( (未設(shè)專門輸出函數(shù))未設(shè)專門輸出函數(shù))析構(gòu)函數(shù)在程序結(jié)束析構(gòu)函數(shù)在程序結(jié)束前由系統(tǒng)自動調(diào)用前由系統(tǒng)自動調(diào)用3.3.拷貝初始化構(gòu)造函數(shù)拷貝初始化構(gòu)造函數(shù) 例例6.56.5#include iostream.hclass Circle1private: double x,y,r,s; public: void print() cout圓心圓心:(x,y)endl; cout半徑半徑:rendl; Circle1(double x1,double y1,double r1) x=x1; y=y1;

21、 r=r1;Circle1( Circle1 &p)x=p.x; y=p.y, r=p.r;void main()Circle1 p1(0,0,2),p2(p1); p1.print(); p2.print();用于用已知對象初始化被創(chuàng)建的同類對象用于用已知對象初始化被創(chuàng)建的同類對象只有一個參數(shù),且是對某個對象的引用只有一個參數(shù),且是對某個對象的引用常用于做函數(shù)的形參及返回值常用于做函數(shù)的形參及返回值拷貝初始化構(gòu)造函拷貝初始化構(gòu)造函數(shù)數(shù)( (引用做參數(shù)引用做參數(shù)) )已知對象已知對象做初值做初值.4常對象和常成員常對象和常成員 1.1.常成員函數(shù)常成員函數(shù)形式:形式:類型說明符

22、類型說明符 函數(shù)名函數(shù)名( (參數(shù)表參數(shù)表) ) constconst不修改對象數(shù)據(jù)成員的成員函數(shù)才能聲明為不修改對象數(shù)據(jù)成員的成員函數(shù)才能聲明為constconst函數(shù)函數(shù)構(gòu)造函數(shù)和析構(gòu)函數(shù)不能聲明為構(gòu)造函數(shù)和析構(gòu)函數(shù)不能聲明為constconst只有常成員函數(shù)可以操作常對象只有常成員函數(shù)可以操作常對象說明:說明: 例例6.66.6常成員函數(shù)示例常成員函數(shù)示例#include iostream.hclass Timeprivate: int hour,minute,second; public: Time:Time() Time:Time(int h,int m,int s) hour=h;

23、 minute=m; second=s; void settime(int h,int m,int s) hour=h; minute=m; second=s; void print()const couthour:minute:secondendl;void main()Time t1; const Time t2(10,23,34);/定義定義t2為常對象為常對象 t1.settime(11,15,20); t1.print(); /t2.settime(4,12,15); t2.print();前面的解釋符可去掉嗎前面的解釋符可去掉嗎不修改數(shù)據(jù)成員,不修改數(shù)據(jù)成員,定義為常函數(shù)定義為常函

24、數(shù)settime函數(shù)可函數(shù)可聲明為聲明為const嗎嗎2.2.常數(shù)據(jù)成員常數(shù)據(jù)成員 對不應(yīng)該被修改的數(shù)據(jù)成員聲明為對不應(yīng)該被修改的數(shù)據(jù)成員聲明為constconst,可使其受,可使其受到強制保護,初始化方式與一般數(shù)據(jù)成員不同。到強制保護,初始化方式與一般數(shù)據(jù)成員不同。class Decrement private: int num; const int dec; /將將dec聲明為常數(shù)據(jù)成員聲明為常數(shù)據(jù)成員 public: Decrement(int n,int d):dec(d) num=n; void fdec() num=num-dec; void print()const coutnu

25、m=num,dec=decendl; ;初始化列表的初始化列表的方式初始化方式初始化.5靜態(tài)成員靜態(tài)成員 靜態(tài)成員的提出是為了解決靜態(tài)成員的提出是為了解決數(shù)據(jù)共享數(shù)據(jù)共享的問題,它比全局變的問題,它比全局變量在實現(xiàn)數(shù)據(jù)共享時更為安全,是實現(xiàn)同類多個對象數(shù)據(jù)共享量在實現(xiàn)數(shù)據(jù)共享時更為安全,是實現(xiàn)同類多個對象數(shù)據(jù)共享的好方法。在類中,分為靜態(tài)數(shù)據(jù)成員和靜態(tài)函數(shù)。的好方法。在類中,分為靜態(tài)數(shù)據(jù)成員和靜態(tài)函數(shù)。1 1。靜態(tài)數(shù)據(jù)成員。靜態(tài)數(shù)據(jù)成員初始化格式:初始化格式:數(shù)據(jù)類型數(shù)據(jù)類型 類名類名:靜態(tài)數(shù)據(jù)成員靜態(tài)數(shù)據(jù)成員= =值值是類的成員,被所有對象所共享,在內(nèi)存中只存貯一次是類的成員

26、,被所有對象所共享,在內(nèi)存中只存貯一次定義或說明時前面加關(guān)鍵字定義或說明時前面加關(guān)鍵字staticstatic初始化在類外進行,不加初始化在類外進行,不加staticstatic和訪問權(quán)限修飾符和訪問權(quán)限修飾符 例例6.7 6.7 靜態(tài)數(shù)據(jù)成員示例程序靜態(tài)數(shù)據(jù)成員示例程序 通過以下程序了解靜態(tài)數(shù)據(jù)成員的聲明、初始化的位置通過以下程序了解靜態(tài)數(shù)據(jù)成員的聲明、初始化的位置和限定及具有類對象共享的屬性。和限定及具有類對象共享的屬性。#include class Tcprivate: int i; static int k; public: Tc( ) i=0; i+; k+; void displa

27、y() couti,1創(chuàng)建創(chuàng)建B時時k值值1-2。1,21,22.2.靜態(tài)成員函數(shù)靜態(tài)成員函數(shù)調(diào)用形式調(diào)用形式: 靜態(tài)成員函數(shù)中數(shù)據(jù)成員的引用也有區(qū)別靜態(tài)成員函數(shù)中數(shù)據(jù)成員的引用也有區(qū)別: 例例6.8靜態(tài)成員函數(shù)應(yīng)用程序示例靜態(tài)成員函數(shù)應(yīng)用程序示例靜態(tài)成員函數(shù)是類的成員函數(shù)靜態(tài)成員函數(shù)是類的成員函數(shù),而非對象的成員。而非對象的成員。類名類名:靜態(tài)成員函數(shù)名靜態(tài)成員函數(shù)名( (參數(shù)表參數(shù)表) )對靜態(tài)數(shù)據(jù)成員,直接引用對靜態(tài)數(shù)據(jù)成員,直接引用對非靜態(tài)數(shù)據(jù)成員,通過對象引用對非靜態(tài)數(shù)據(jù)成員,通過對象引用#include class Tcprivate: int A; static int B; p

28、ublic: Tc(int a) A=a; B+=a; static void display(Tc C) coutC.AB; ;int Tc:B=2;void main() Tc A(2),B(4); Tc:display(A); Tc:display(B); 靜態(tài)成靜態(tài)成員函數(shù)員函數(shù)的調(diào)用的調(diào)用非靜態(tài)數(shù)非靜態(tài)數(shù)據(jù)成員的據(jù)成員的引用引用靜態(tài)數(shù)據(jù)靜態(tài)數(shù)據(jù)成員的引成員的引用用 通過該程序了解通過該程序了解程序程序中靜態(tài)成員函數(shù)的調(diào)用方式以及中靜態(tài)成員函數(shù)的調(diào)用方式以及靜態(tài)靜態(tài)成員函數(shù)成員函數(shù)中靜態(tài)數(shù)據(jù)成員和非靜態(tài)數(shù)據(jù)成員的引用方式中靜態(tài)數(shù)據(jù)成員和非靜態(tài)數(shù)據(jù)成員的引用方式6.3.6 6.3.6 友

29、元函數(shù)友元函數(shù) 例例6.96.9友元函數(shù)示例程序友元函數(shù)示例程序#include #include class Cpointprivate: int X,Y; public: Cpoint(int x, int y) X=x; Y=y; void print(); friend double dist(Cpoint &a,Cpoint &b); ;void Cpoint:print() coutXY ;double dist(Cpoint &a,Cpoint &b) int dx=a.X-b.X; int dy=a.Y-b.Y; return sqrt(dx*dx+dy*dy);void ma

30、in()Cpoint p1(3,4),p2(6,8); p1.print(); p2.print(); double d=dist(p1,p2); /*友元不是成友元不是成員函數(shù)不需對象表示,直接調(diào)用員函數(shù)不需對象表示,直接調(diào)用*/ coutDistance is dendl; 友元函數(shù)說明友元函數(shù)說明前不能加前不能加 friend為非成員函數(shù)為非成員函數(shù)可訪問類中私有成員可訪問類中私有成員說明時前面加關(guān)鍵字說明時前面加關(guān)鍵字friendfriend標(biāo)識標(biāo)識計算機系人員計算機系人員學(xué)生學(xué)生研究生研究生本科生本科生系主任系主任行政管理人員行政管理人員教務(wù)教務(wù)教師教師教職工教職工6.4 6.4 繼

31、承和派生繼承和派生基類基類(父類)(父類)派生類派生類(子類)(子類)多繼承多繼承單繼承單繼承class Cylinder1:public Circleprivate: double h; public: void print() Circle:print(); cout圓柱高圓柱高:hendl; void set(double x1,double y1, double r1,double h1) Circle:set(x1,y1,r1); h=h1; ;class Cylinderprivate: double x,y,r,h; public: void print() cout圓心圓心:(

32、x, y)endl; cout半徑半徑:r ,圓柱高圓柱高:hendl; void set(double x1,double y1, double r1,double h1) x=x1; y=y1; r=r1; h=h1;對比如下兩個圓柱體類的定義對比如下兩個圓柱體類的定義全部數(shù)據(jù)成全部數(shù)據(jù)成員重新定義員重新定義只定義一個新成只定義一個新成員員(Circle中沒有)中沒有)通過調(diào)用通過調(diào)用Circle類成員類成員函數(shù)輸出函數(shù)輸出Circle類成員類成員從從Circle類類中派生而來中派生而來.2單繼承單繼承 1.1.派生類的定義格式派生類的定義格式原有類(父類)原有類(父類)c

33、lass 派生類名派生類名: 繼承方式繼承方式 基類名基類名 派生類新定義成員;派生類新定義成員;public(公有基類公有基類)private(私有基類私有基類)protected(保護基類保護基類) 若要在派生類若要在派生類Cylinder1Cylinder1中再增加一個成員函數(shù)中再增加一個成員函數(shù)volumevolume,用以求圓柱體的體積,則該成員函數(shù)能否如,用以求圓柱體的體積,則該成員函數(shù)能否如下實現(xiàn):下實現(xiàn):double Cylinder1:volume()return(3.14*r*r*h);錯!錯!r r是是CircleCircle類的私有成員,類的私有成員,不能被派生類訪問不

34、能被派生類訪問2.2.繼承方式繼承方式 public,private和和protected 是三種常用的繼承方式,繼承方式的不是三種常用的繼承方式,繼承方式的不同決定了派生類對基類成員的訪問權(quán)限不同。同決定了派生類對基類成員的訪問權(quán)限不同。基類基類私有成員私有成員(privateprivate) 公有成員公有成員(publicpublic)保護成員保護成員(protected)(protected)私有派生類私有派生類(privateprivate)不可訪問的成員不可訪問的成員私有成員私有成員私有成員私有成員公有派生類公有派生類(publicpublic)不可訪問的成員不可訪問的成員公有成員公

35、有成員保護成員保護成員保護派生類保護派生類(protected)(protected)不可訪問的成員不可訪問的成員保護成員保護成員保護成員保護成員派生類的繼承關(guān)系派生類的繼承關(guān)系 例例6.106.10分析下列程序中的訪問權(quán)限,并回答所提的問題。分析下列程序中的訪問權(quán)限,并回答所提的問題。#include class Apublic: void f1(); A( ) i1=10;j1=11; protected: int j1; private: int i1; ;class B:public Apublic: void f2( ); B( ) i2=20;j2=21; protected: i

36、nt j2; private: int i2; ;class C:public Bpublic: void f3(); C( ) i3=30;j3=31; protected: int j3; private: int i3; ;void main()A a; B b; C c; (1) f2()能否訪問能否訪問f1(),i1,j1?能訪問能訪問f1()、j1,不能訪問不能訪問i1(2) 能否訪問能否訪問f(),i1,j1?能訪問能訪問f1(),不能訪問不能訪問i1和和j1(3) f3()能否訪問能否訪問f2()、i2和和j2,以及以及f1(),j1和和i1?f3能訪問能訪問f2()和和j2,

37、以及以及f1()和和j1,但不能訪問,但不能訪問i1和和i2(4)c能否訪問能否訪問f2(),i2和和j2?以及以及f1(),j1和和i1?能訪問能訪問f2()和和f1(),其它的都,其它的都不能訪問不能訪問#include iostream.hclass Circleprivate: double x,y,r; public: void print() cout圓心圓心:(x,y); coutendl半徑半徑:rendl; void set(double x1,double y1,double r1) x=x1; y=y1; r=r1; double getr() return r;clas

38、s Cylinder1:public Circleprivate: double h; public: void print() Circle:print(); cout圓柱高圓柱高:hendl; void set(double x1,double y1, double r1,double h1) Circle:set(x1,y1,r1); h=h1; double volume() double R=getr(); return(3.14*R*R*h); ;void main()Cylinder1 p; p.set(0,0,2,3); p.print(); coutvolume=p.volu

39、me(); 該函數(shù)返回值為圓半徑,為派該函數(shù)返回值為圓半徑,為派生類能使用半徑提供一個接口生類能使用半徑提供一個接口 派生類可訪問派生類可訪問基類公有成員基類公有成員 例例6.116.11派生類示例程序派生類示例程序3.3.構(gòu)造函數(shù)和析構(gòu)函數(shù)構(gòu)造函數(shù)和析構(gòu)函數(shù) 派生類的構(gòu)造函數(shù)除了對自己的數(shù)據(jù)成員初始化外,還負(fù)責(zé)調(diào)用派生類的構(gòu)造函數(shù)除了對自己的數(shù)據(jù)成員初始化外,還負(fù)責(zé)調(diào)用基類構(gòu)造函數(shù)使基類的數(shù)據(jù)成員得以初始化,當(dāng)對象被刪除時,派生基類構(gòu)造函數(shù)使基類的數(shù)據(jù)成員得以初始化,當(dāng)對象被刪除時,派生類的析構(gòu)函數(shù)被執(zhí)行,同時基類的析構(gòu)函數(shù)也將被調(diào)用。類的析構(gòu)函數(shù)被執(zhí)行,同時基類的析構(gòu)函數(shù)也將被調(diào)用。格式:

40、格式:派生類名派生類名( (派生類構(gòu)造函數(shù)總參數(shù)表派生類構(gòu)造函數(shù)總參數(shù)表):):基類構(gòu)造函數(shù)基類構(gòu)造函數(shù)( (參數(shù)表參數(shù)表1)1) ; 基類中有缺省的構(gòu)造函數(shù)或沒定義構(gòu)造函數(shù),則派生類構(gòu)造函數(shù)的基類中有缺省的構(gòu)造函數(shù)或沒定義構(gòu)造函數(shù),則派生類構(gòu)造函數(shù)的定義中可省略對基類構(gòu)造函數(shù)的調(diào)用,而隱式調(diào)用缺省構(gòu)造函數(shù)。定義中可省略對基類構(gòu)造函數(shù)的調(diào)用,而隱式調(diào)用缺省構(gòu)造函數(shù)。基類構(gòu)造函數(shù)中,只有有參的構(gòu)造函數(shù),則派生類構(gòu)造函數(shù)中必須基類構(gòu)造函數(shù)中,只有有參的構(gòu)造函數(shù),則派生類構(gòu)造函數(shù)中必須 調(diào)用基類構(gòu)造函數(shù),提供將參數(shù)傳遞給基類構(gòu)造函數(shù)的途徑調(diào)用基類構(gòu)造函數(shù),提供將參數(shù)傳遞給基類構(gòu)造函數(shù)的途徑派生類構(gòu)造

41、函數(shù)的調(diào)用順序為先基類,后派生類。派生類構(gòu)造函數(shù)的調(diào)用順序為先基類,后派生類。派生類析構(gòu)函數(shù)的執(zhí)行順序為先派生類,后基類。派生類析構(gòu)函數(shù)的執(zhí)行順序為先派生類,后基類。 說明:說明:#includeiostream.h#include string.hclass Staffprivate: char name30; char sex; float wage; public:void display()coutname:sex, ageendl; Staff(char *n,char s,float w) strcpy(name,n); sex=s; wage=w; ;class Staff1:p

42、ublic Staffprivate: int wt;public:Staff1(char *n,char s,float w,int t):Staff(n,s,w)wt=t;double addwage()return(wt/10*80);void display() Staff:display(); coutwt, addwage()endl;void main()Staff1s(WangQiang,m,1526,21); s.display(); 例例6.126.12派生類構(gòu)造函數(shù)示例程序派生類構(gòu)造函數(shù)示例程序派生類構(gòu)造函數(shù)中派生類構(gòu)造函數(shù)中調(diào)用基類構(gòu)造函數(shù)調(diào)用基類構(gòu)造函數(shù) 6.56.5

43、多態(tài)性多態(tài)性 發(fā)出同樣的消息被不同類型的對象接收時導(dǎo)致完發(fā)出同樣的消息被不同類型的對象接收時導(dǎo)致完全不同的行為。全不同的行為。函數(shù)重載(已介紹過)函數(shù)重載(已介紹過)運算符重載運算符重載基于虛函數(shù)的多態(tài)性基于虛函數(shù)的多態(tài)性6.5.1 6.5.1 運算符重載運算符重載 賦予已有的運算符多重含義,通過重新定義運賦予已有的運算符多重含義,通過重新定義運算符使它能夠用于特定類的對象以完成特定的功能。算符使它能夠用于特定類的對象以完成特定的功能。 例例6.136.13重載重載“+”+”運算運算 ,用以實現(xiàn)兩個字符串的連,用以實現(xiàn)兩個字符串的連接接 #include iostream.h#include

44、string.h#include stdio.hclass Strprivate: char *s; int len; public: Str() Str(char *s1) len=strlen(s1); s=new charlen; strcpy(s,s1); void print() coutsendl; Str operator+(Str s1) return(strcat(s,s1.s); ;void main() char str1100,str2100; gets(str1); gets(str2); Str s1(str1),s2(str2),s3; s3=s1+s2; s3.

45、print();對加法運算對加法運算符進行重載符進行重載 s3=s1.operator+(s2)s3=s1.operator+(s2) 重載形式:重載形式:重載為類的成員函數(shù):重載為類的成員函數(shù):類名類名 operator 運算符運算符( (參數(shù)表參數(shù)表) )程序中表達形式:程序中表達形式:c1 c1 運算符運算符 c2c2編譯程序解釋形式:編譯程序解釋形式:c1 operator c1 operator 運算符運算符( (c2)c2)重載為類的友元函數(shù):重載為類的友元函數(shù):friend類名類名operator運算符運算符( (參數(shù)表參數(shù)表) )程序中表達形式:程序中表達形式:c1 c1 運算

46、符運算符 c2c2編譯程序解釋形式:編譯程序解釋形式:operator operator 運算符運算符( (c1,c2)c1,c2)將例將例6.13中的加法運算符重載為友元函數(shù)的形式如下:中的加法運算符重載為友元函數(shù)的形式如下:friend Str operator+(Str s1,Str s2)return(strcat(s1.s,s2.s);隱含了指向隱含了指向c1的的this指針指針this 指針指針 無需定義而隱含于每個類的成員函數(shù)中無需定義而隱含于每個類的成員函數(shù)中指向正在被某個成員函數(shù)操作的對象指向正在被某個成員函數(shù)操作的對象可以用可以用* *thisthis來標(biāo)識調(diào)用該成員函數(shù)的

47、對象來標(biāo)識調(diào)用該成員函數(shù)的對象通常情況下,程序中并不顯式地使用通常情況下,程序中并不顯式地使用thisthis指針指針 例例6.146.14自增運算符重載(自增運算符重載(this 指針使用示例)指針使用示例)#include iostream.hclass Aprivate: int x; public: A(int x1) x=x1; void print() coutxendl; A operator+() x+; return(*this); ;void main()A a(5); (+a).print();返回調(diào)用成員函返回調(diào)用成員函數(shù)的對象自身數(shù)的對象自身 自增重載運算作自增重載運

48、算作用于用于A A類對象類對象a a等價于如下兩條語句:等價于如下兩條語句:+a;a.print();.3虛函數(shù)虛函數(shù)虛函數(shù)說明方式虛函數(shù)說明方式 虛函數(shù)是動態(tài)聯(lián)編的基礎(chǔ),它是一種非虛函數(shù)是動態(tài)聯(lián)編的基礎(chǔ),它是一種非staticstatic的成員函數(shù)的成員函數(shù)實現(xiàn)動態(tài)聯(lián)編的條件實現(xiàn)動態(tài)聯(lián)編的條件virtual 類型說明符類型說明符 函數(shù)名函數(shù)名 ( (參數(shù)表參數(shù)表) )基基類中有說明的類中有說明的虛函數(shù)虛函數(shù)調(diào)用虛函數(shù)操作的只能是對象指針或?qū)ο笠?,調(diào)用虛函數(shù)操作的只能是對象指針或?qū)ο笠?,否則仍為靜態(tài)聯(lián)編否則仍為靜態(tài)聯(lián)編 例例6.156.15虛函數(shù)示例程序虛函數(shù)示例程序 #i

49、nclude iostream.hclass Animalpublic: void character() cout動物特征動物特征: :不同不同.n; virtual food() cout動物食物動物食物: :不同不同.n;class Giraffe:public Animalpublic: void character() cout長頸鹿特征長頸鹿特征: :長頸長頸.n; virtual food() cout長頸鹿食物長頸鹿食物: :樹葉樹葉.n;class Elephant:public Animalpublic: void character()cout大象特征大象特征: :長鼻子

50、長鼻子.n; virtual food() coutcharacter(); p-food();void main()Giraffe g; f(&g);/實參為派生類對象的地址實參為派生類對象的地址 Elephant e; f(&e);/實參為派生類對象的地址實參為派生類對象的地址觀察運行結(jié)果觀察運行結(jié)果void f(Animal &p)/形參為基類形參為基類對象的引用對象的引用p.character(); p.food();void main()Giraffe g; f(g);/實參為派生類對象實參為派生類對象 Elephant e; f(e);/實參為派生類對象實參為派生類對象void f

51、(Animal p)/形參為基類形參為基類對象對象p.character(); p.food();void main()Giraffe g; f(g);/實參為派生類對象實參為派生類對象 Elephant e; f(e);/實參為派生類對象實參為派生類對象若將程序的相應(yīng)部分修改為如下兩種形式,再觀察運行結(jié)果若將程序的相應(yīng)部分修改為如下兩種形式,再觀察運行結(jié)果從上述程序中可見:從上述程序中可見: 只有當(dāng)虛函數(shù)操作的是指向?qū)ο蟮闹羔樆蚴菍ο蟮囊脮r,只有當(dāng)虛函數(shù)操作的是指向?qū)ο蟮闹羔樆蚴菍ο蟮囊脮r,對該虛函數(shù)調(diào)用采取的才是動態(tài)聯(lián)編。對該虛函數(shù)調(diào)用采取的才是動態(tài)聯(lián)編。虛函數(shù)使用說明:虛函數(shù)使用說明

52、:派生類中的虛函數(shù)應(yīng)與基類中的虛函數(shù)具有相同派生類中的虛函數(shù)應(yīng)與基類中的虛函數(shù)具有相同的名稱、參數(shù)個數(shù)及參數(shù)類型。的名稱、參數(shù)個數(shù)及參數(shù)類型。 可以只將基類中的成員函數(shù)顯式地說明為虛函可以只將基類中的成員函數(shù)顯式地說明為虛函數(shù),而派生類中的同名函數(shù)也隱含為虛函數(shù)。數(shù),而派生類中的同名函數(shù)也隱含為虛函數(shù)。1.1.純虛函數(shù)純虛函數(shù) 是一種沒有函數(shù)體特殊的虛函數(shù),當(dāng)在基類中不能對虛函數(shù)是一種沒有函數(shù)體特殊的虛函數(shù),當(dāng)在基類中不能對虛函數(shù)給出有意義的實現(xiàn),而將其說明為純虛函數(shù),它的實現(xiàn)留給派生給出有意義的實現(xiàn),而將其說明為純虛函數(shù),它的實現(xiàn)留給派生類去做。類去做。格式:格式:6.5.4 6.5.4 抽

53、象類抽象類 virtual 類型類型 函數(shù)名函數(shù)名 ( (參數(shù)表參數(shù)表)=0)=0;2. 2. 抽象類抽象類 是帶有純虛函數(shù)的特殊類,主要作用是將有關(guān)的子類組織是帶有純虛函數(shù)的特殊類,主要作用是將有關(guān)的子類組織在一個繼承層次結(jié)構(gòu)中,由它來為它們提供一個公共的根。在一個繼承層次結(jié)構(gòu)中,由它來為它們提供一個公共的根。只能用作其它類的基類,只能用作其它類的基類,不能建立抽象類對象不能建立抽象類對象可說明抽象類可說明抽象類指針和引用指針和引用,指向其,指向其派生類派生類,進而實現(xiàn)多態(tài)性。,進而實現(xiàn)多態(tài)性。不能用作參數(shù)類型、函數(shù)返回類型或強制轉(zhuǎn)換的類型。不能用作參數(shù)類型、函數(shù)返回類型或強制轉(zhuǎn)換的類型。

54、例例6.166.16抽象類示例程序抽象類示例程序#include #include class baseprotected: int x,y;public: virtual void setx(int i,int j=0) x=i; y=j; virtual void disp()=0; ;class square: public basepublic: void disp() coutx*xendl; ;class cube: public basepublic: void disp() coutx*x*xendl; ;class chpow: public basepublic: void disp() coutsetx(5); ptr-disp(); ptr=&C; ptr-

溫馨提示

  • 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

提交評論