第5章C++語言進階_第1頁
第5章C++語言進階_第2頁
第5章C++語言進階_第3頁
第5章C++語言進階_第4頁
第5章C++語言進階_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第5章C+語言進階教學提示:在第4章已經介紹了C+中關于類的大部分內容,本章繼續(xù)講解和類相關的內容。主要包括:友元,this指針,類的繼承,多態(tài)和虛擬函數等,它們是編寫面向對象程序的基礎。教學目標:掌握友元函數和友元類的概念,掌握友元的使用,理解友元的局限性;理解this指針的概念;理解多態(tài)性的含義,多態(tài)對于繼承的意義,掌握多態(tài)的工作原理;理解抽象類與具體類的區(qū)別;熟練運用類的繼承、類的多重繼承、虛函數、純虛函數,編寫層次分明、結構清晰的程序。5.1 友元和this指針5.1.1 友元1. 友元函數在第3章重載運算符時已經用到了友元函數,但并沒有對友元函數作詳細的介紹。其實,友元函數和普通的C

2、+函數不同的只是,它可以訪問類的保護和私有成員。利用友元函數使程序編寫更加方便,提高了效率。但是使用友元函數破壞了類的封裝性,因此一般只在能夠提高程序效率的前提下使用友元。定義友元函數很簡單,在類里聲明一個普通函數,標上關鍵字friend,就成了該類的友元,就可以訪問該類的一切成員。例如,下面的例子定義了兩個類,rect類和point類,并聲明函數inrect是它們的友元函數,因此inrect函數可以訪問rect類和point類中的非公有成員。 class rect; class point private: int x; int y; public: point(int xx=0,int y

3、y=0):x(xx),y(yy) ; friend int inrect(const point&,const rect&);/聲明友元函數 ; class rect private: point p1; point p2; public: rect(int x1,int y1,int x2,int y2):p1(xl,y1),p2(x2,y2) ; friend int inrect(const point&,const rect&);/聲明友元函數 ; /友元函數的定義 int inrect(const point &p,const rect &r) /友元函數內可以訪問類的私有成員 if

4、(p.x=r.p2.x)&(p.y=r.p2.y) return l; if(p.x=r.p1.x)&(p.x=r.p1.y)&(p.y=r.p2.y) return 1; return 0; 友元函數不是類的成員函數,但它是類的朋友,因而友元函數也可以訪問類的全部成員。友元函數的聲明可以放在類定義的任何部位,可以在public區(qū),也可以放在private區(qū),意義完全相同。友元函數的定義部分在類定義體的外面,一般和類的成員函數放在一起,以便在類重用時,友元函數可以一起重用。2.友元成員函數當一個類的某個成員函數被宣布為另一個類的友元時,在這個成員函數內就可以訪問另一個類的非公有數據。例如: c

5、lass student; class teacher public: void teacher:setscore(student &s,int i) s.score=i; ; class student private: int score; public: friend void teacher:setscore(student &s,int i); ; teacher類的成員函數setscore(student&s,int i) 被聲明為student類的友元,因此teacher類的對象可以通過其成員函數setscore修改student類對象的非公有數據成員。例如: student s

6、1; teacher t1; t1.setscore(s1,90);3. 友類整個類是另一個類的友元,該友元稱為友類,友類的每個成員函數都可以訪問另一個類的保護或私有的數據成員。即,當類A宣布為類B的友類時,類A的所有成員函數都可以訪問類B的非公有成員。例如: class student; class teacher public: void teacher:setscore(student &s,int i) s.score=i; ; class student private: int score; public: friend class teacher;/友類 / ;友元的作用主要是為

7、了提高效率和方便編程,但隨著硬件性能的迅速提高,友元的這點作用已經微不足道,相反,友元破壞了類的封裝性,破壞了類的整體操作。所以我們不鼓勵使用友元,讀者在使用友元時要權衡利弊。5.1.2 this指針this指針隱含于每一個類的成員函數中(靜態(tài)成員函數除外),它指向調用該成員函數的對象。當一個對象調用成員函數時,編譯程序先將對象的指針地址賦值給this指針,然后調用成員函數,每次成員函數存取數據時都隱含地使用了this指針。通常不顯式地使用this指針來引用數據成員??梢杂?this來標識調用成員函數的對象。 class room private: int m; public: room(in

8、t i,int j); void view( ) cout”m=”mendl; /隱含了this指針 cout”m=”mendl;/和上一行的效果相同 ; 例題:分析下面程序的輸出結果:/5_1.cpp#include class sampleprivate:int x,y;public:sample( ) sample(int a,int b)x=a;y=b;void copy(sample &c)if(this=&c)cout錯誤的復制調用endl;/return;elsec.view();void square()x=x*x;y=y*y;void view()coutx=x y=yend

9、l;void main()sample c1,c2(5,5);c2.square();c2.view();c2.copy(c2);c1.copy(c2);程序的執(zhí)行結果是: 25 25 錯誤的復制調用 25 255.2 靜態(tài)成員為了解決數據的共享問題,C+中提出了靜態(tài)成員的概念。靜態(tài)成員分為靜態(tài)成員函數和靜態(tài)成員變量兩種。將數據成員聲明為靜態(tài)的,將使所有的同類對象都擁有同一份靜態(tài)成員,該靜態(tài)成員遵守數據封裝約定。使用靜態(tài)成員可以節(jié)省內存,因為它是所有對象共有的,只需存儲一處,就可以供所有對象使用。靜態(tài)成員對所有的對象都一樣,它的值是可以改變的。類的所有對象都共用static類成員。關鍵字sta

10、tic可以用來定義類的成員。如果將類的某個成員聲明為static,那么你也就告訴編譯器:無論創(chuàng)建了多少個類對象,程序中也只有一個static成員的副本。也就是說,類的所有對象都將共用static成員。如果在創(chuàng)建第一個類對象時沒有對static成員進行初始化,那么類中所有的static成員都被初始化為零。當你在類中聲明一個static成員時,你并沒有定義它,所以必須為這個static成員提供一個在類作用域之外的全局定義。我們通過在全局作用域中重新聲明static成員變量來定義它,并且使用作用域解析運算符來指定它所在的類。在程序中對static成員變量的定義為static成員變量分配了內存空間。5

11、.2.1 靜態(tài)數據成員靜態(tài)數據成員的使用方法:(1) 靜態(tài)數據成員在聲明時前面加static關鍵字。(2) 靜態(tài)數據成員的初始化和一般數據成員的初始化不同,靜態(tài)數據成員初始化格式如下: :=;初始化在類體外進行,前面不加static,以免與一般的靜態(tài)變量或者對象混淆。初始化時不加該成員的訪問權限控制符public、protected和private。初始化時使用作用域運算符表明該成員所屬的類,因此,靜態(tài)數據成員是類的成員,它不是任何對象獨占的成員。(3) 靜態(tài)數據成員必須初始化。(4) 用類名引用靜態(tài)數據成員: :(5) 類和對象都可以對靜態(tài)數據成員進行改動。下面的示例程序使用到了static

12、變量,請仔細閱讀程序并理解程序是如何運行的。/補充例題:(5_2_1.cpp)注意,我們在類ShareVar中聲明了靜態(tài)整數變量num,同時還在程序中將num作為一個全局變量來定義。前面提到過,這樣做是必須的,因為在類ShareVar中我們只是聲明變量num而沒有為它分配內存。由于在程序中沒有對變量num作初始化,所以C+默認將num初始化為0,因此第一次調用函數shownum()時,程序輸出0。接下來,對象a將num的值設置為10。然后,對象a和b都調用函數shownum()來輸出num的值。因為在程序中變量num只有一個副本,并且由對象a和b共用,所以兩個函數都將輸出10。#include

13、 class ShareVar static int num;public: void setnum(int i) num = i; ; void shownum() cout num ; ;/ 定義類ShareVar的靜態(tài)成員變量numint ShareVar : num ; int main() ShareVar a, b; a.shownum(); / 輸出 0 b.shownum(); / 輸出 0a. setnum(10); / 將靜態(tài)成員變量num的值設為10 a.shownum(); / 輸出 10 b.shownum(); / 也輸出 10 return 0;l 記?。喝绻陬?/p>

14、中某個成員被聲明為static,那么這個成員在程序中就只有一個副本,然后類的所有對象都將共用這個副本。如果static成員變量是類的公有成員,那么可以直接通過類的名字而不是對象的名字來使用這個成員(當然,也可以通過對象的名字來使用)。例如,考慮下面的類ShareVar:class ShareVarpublic: static int hum; void setnum(int i) num = i; ; void shownum() cout num ; ;在上面的定義中,成員變量num是公有的,因此可以直接訪問變量num,如下所示:ShareVar:num=100;上面這條語句是通過類的名字和

15、作用域解析運算符來訪問變量num,這與類的對象無關。而且,甚至在任何ShareVar類型的對象存在之前,這條語句都是有效的!這樣,你可以在創(chuàng)建任何對象之前獲得或者設置類的static成員變量的值。下面的程序定義了一個靜態(tài)數據成員n,在構造函數中定義了n的自增運算,調用一次構造函數,n加1。/5_2.cpp#include class roomprivate: int m;public: static int n; /聲明靜態(tài)數據變量 room(int i):m(i) n+; void view() coutm=mendl; coutn=nendl; room( ) ;int room:n=0;

16、 /靜態(tài)成員只能在類外部定義,定義的同時必須初始化。void main() room r1(10);/每當調用一次構造函數,n加1。 room r2(20);/r2構造結束后n=2 room r3(30);/r3構造結束后n=3 coutin class room n=room:nendl;/引用靜態(tài)成員可以用類名程序的執(zhí)行結果是: in class room n=35.2.2 靜態(tài)成員函數成員函數也可以被聲明為static,但這種用法并不普遍。靜態(tài)成員函數和靜態(tài)數據成員一樣,它們都屬于類的靜態(tài)成員,而不是對象的成員。static成員函數可以通過類的對象來調用,或者也可以不依賴于任何對象而使用

17、類的名字和作用域解析運算符來調用。在靜態(tài)成員函數的實現(xiàn)中不能直接引用類的非靜態(tài)成員,也不能引用this指針,但可以引用類中聲明的靜態(tài)成員(當然,static成員函數也可以訪問全局變量和全局函數)。如果靜態(tài)成員函數中需要引用非靜態(tài)成員時,可以通過對象來引用。下面的類room定義了靜態(tài)成員函數view();它可以引用類的靜態(tài)成員變量n,但是不能引用非靜態(tài)成員變量m。 class room private: int m; public: static int n; room(int i):m(i) n+; static void view( ) /靜態(tài)成員函數 m+; /error這里不能引用非靜態(tài)

18、成員 cout”n=”nendl; ;int room:n=0;/定義并初始化靜態(tài)數據成員n=0下面的程序定義了一個學生類,該類共定義了4個靜態(tài)成員,一個整型靜態(tài)成員變量count,它的作用是計數器,用來記錄學生的個數;一個student類類型的指針靜態(tài)成員變量pfirst,用來記錄鏈頭指針;一個返回值為空的靜態(tài)成員函數findname(),它的功能是從鏈頭開始查找某個特定的節(jié)點,函數體內設置了一個for循環(huán),循環(huán)從鏈頭開始查找,一直查到鏈尾,如果找到了關鍵節(jié)點,則輸出關鍵節(jié)點在鏈表中的位置,結束循環(huán),如果沒有找到則輸出“no find并返回;一個返回值為空的靜態(tài)成員函數view(),它的功能

19、是對鏈表進行遍歷,并在屏幕上依次輸出各個節(jié)點的name域的值。調用一次student類的成員函數,就在鏈表頭插入一個節(jié)點,新插入節(jié)點的pnext指針指向插入前的頭節(jié)點。鏈表開始時為空,即pfirst為空。具體代碼如下:/5_3.cpp#include #include class studentprivate:char name40;int number;static int count; /計數器,用來記錄學生的個數static student* pfirst; /鏈表頭指針,student *pnext; /指向鏈表當前節(jié)點的下一個節(jié)點public:student(char *);stud

20、ent();static void findname(char *); /查詢特定節(jié)點static void view(); /遍歷鏈表;int student:count=0; /定義并賦初值0student* student:pfirst=NULL; /定義并賦初值NULL/student類的成員函數student:student(char *pname)strcpy(name,pname);pnext=pfirst;pfirst=this;count+;number=count;/student類的析構函數student:student( ) /析構函數if(pfirst=this)pf

21、irst=pnext;count-;return;for(student* ps=pfirst;ps;ps=ps-pnext)if(ps-pnext=this)ps-pnext=pnext;count-;return;void student:findname(char* pname) /在鏈表中查找某個關鍵節(jié)點for(student* ps=pfirst;ps;ps=ps-pnext)if(strcmp(ps-name,pname)=0)coutfind it,it is number numberendl;return;coutno findpnext)coutnameendl;void

22、main()student s1(s1);student s2(s2);student s3(s3);student:view();char name40;coutplease put in the name of which you want to findname;student:findname(name);程序運行結果如下: sl s2 s3 please put in the name of which you want to find s2(假如你輸入的是s2) find it,it is number 25.3 繼 承繼承性是面向對象程序設計中最重要的機制,這一機制提供了無限重復

23、利用程序資源的有效途徑,該機制自動為一個類提供來自另一個類的操作和數據結構。程序員通過C+語言中的繼承機制,可以擴充舊的程序以適應新的需求,這樣不僅可以節(jié)約程序開發(fā)時間和資源,并且可以為未來的程序設計增添新的資源。理解繼承性是理解面向對象程序設計所有方面的關鍵。5.3.1 基類和派生類C+語言的繼承機制,允許我們利用已有的數據類型定義新的數據類型,所定義的新數據類型不僅擁有新定義的成員,而且還同時擁有舊的成員。我們稱用來派生新類的類為基類,又叫做父類。由基類派生的新類稱為派生類,也稱為子類。一個派生類可以從一個基類派生,也可以從多個基類派生。從一個基類派生的繼承方式叫做單繼承;從多個基類派生的

24、繼承方式叫做多繼承。任何類都可以作為基類,一個基類可以有一個或者多個派生類,一個派生類還可以成為另一個類的基類。定義單繼承派生類的一般格式如下: class : / 派生類新定義的成員 其中,派生類名稱是新定義的類名,它是從父類中派生的,并且是按照指定的繼承方式派生的。繼承方式有3種,分別是:public方式,表示公有類繼承;protected方式,表示保護基類;private方式,表示私有基類。其中private方式是默認的繼承方式。派生類3種繼承方式的異同闡述如下:(1) public方式這種方式將基類的protected區(qū)成員繼承到派生類的protected區(qū),基類的public區(qū)的成員

25、繼承到派生類的public區(qū)。這時基類能作的所有操作,派生類都可以完成,派生類是基類的子類。對于派生類來說,基類的公有成員和保護成員可見,基類的私有成員不可見,派生類不可以訪問基類的私有成員。對于派生類對象來說,派生類的對象可以訪問基類的公有成員,其他成員是不可見的。注意:在公有繼承時,派生類的對象可以訪問基類的共有成員,派生類的成員函數可以訪問基類的共有成員和保護成員。(2) protected方式這種方式將基類的protected區(qū)和public區(qū)的所有成員都繼承到派生類的protected區(qū)。在這種繼承方式下派生類不是基類的子類。對于派生類來說,基類的公有成員和保護成員是可見的,基類的保

26、護成員和公有成員都作為派生類的保護成員,并且不能被這個派生類的子類訪問;而基類的私有成員是不可見的,派生類不能訪問基類的私有成員:對于派生類的對象來說,基類的所有成員都不可見。所以對于保護繼承來說,基類的成員只能由直接派生類訪問,而無法再往下繼承。(3) private方式將基類的protected區(qū)和public區(qū)的所有成員都繼承到派生類的private區(qū)。在這種繼承方式下派生類也不是基類的子類。對于派生類來說,而基類的公有成員和保護成員是可見的,基類的保護成員和公有成員都作為派生類的私有成員,并且不能被這個派生類的子類訪問:而基類的私有成員是不可見的,派生類不能訪問基類的私有成員;對于派生

27、類的對象來說,基類的所有成員都不可見。所以對于私有繼承來說,基類的成員只能由直接派生類訪問,而無法再往下繼承。如果基類與派生類中都有用戶自定義的構造函數,基類的構造由基類的構造函數完成,派生類的構造函數負責提供派生類和基類的構造參數并構造派生類。由于構造函數不能被繼承,所以派生類的構造函數必須通過調用基類的構造函數來初始化基類的對象。因而在定義派生類的構造函數時,除了對自己的數據成員進行初始化外,還必須負責調用基類構造函數,初始化基類的數據成員。派生類的構造函數一般格式如下:():(), () / 派生類數據成員初始化派生類構造函數的調用順序如下:(1) 基類的構造函數(2) 子對象類的構造函

28、數(3) 派生類的構造函數當對象被刪除時,派生類的析構函數被執(zhí)行。由于析構函數也不能被繼承,因此在執(zhí)行派生類的析構函數時,基類的析構函數也將被調用。執(zhí)行順序是先執(zhí)行派生類的析構函數,再執(zhí)行基類的析構函數,與執(zhí)行構造函數時的順序正好相反。5.3.2 多重繼承多繼承的一般格式:class :,其中,基類可以有兩個或者兩個以上,各個基類之間用逗號隔開,每個基類名前都指明繼承方式,默認的繼承方式是private方式。例如,下面的程序中,類C繼承于兩個基類,一個基類是A,另一個基類是B。/5_4.cpp#include class A /基類A的定義int a;public:A(int i)a=i;co

29、utA constructorendl;void view( )couta=aendl;class B /基類B的定義int b;public:B(int j)b=j;coutB constructorendl;void view()coutb=bendl;class C:public A,public B /定義子類C,它繼承于基類A和基類Bint c;public:/派生類c的構造函數在初始化自己的數據成員時,必須負責調用基類構造函數初始化基類的數據成員。C(int k):A(+k),B(-k)c=k;coutC constructorendl;void view( )A:view( );

30、B:view( );coutc=cendl;void main()C c1(10);c1.view();本程序的執(zhí)行結果是: A constructor B constructor C constructor a=1l b=10 c=105.4 多態(tài)性與虛擬函數學習目標:l 理解多態(tài)性的概念l 理解如何聲明和利用虛擬函數來實現(xiàn)多態(tài)性l 理解抽象類和具體類的區(qū)別l 理解C+如何實現(xiàn)虛擬函數和動態(tài)綁定5.4.1 多態(tài)性C+允許子類的成員函數重載父類的成員函數,程序在運行時能夠依據其類型確認調用哪個函數的能力,稱為多態(tài)性。多態(tài)性是面向對象程序設計的重要特性,是指同一個接口名稱具有多種功能。利用多態(tài)性

31、,用戶只需發(fā)送一般形式的消息,而將所有的實現(xiàn)留給接收消息的對象,對象根據所接收的消息做相應的操作。函數重載和運算符重載就是一類簡單的多態(tài)性。如果語言不支持多態(tài),則不能稱其是面向對象的語言。只支持類不支持多態(tài)的語言,我們稱其為基于對象的。如Ada語言、Visual Basic語言。為了指明某個成員函數具有多態(tài)性,必須用關鍵字virtual聲明其為虛擬函數。例如,下面的程序在它的基類中定義了虛函數fn( ),在派生類中又重新定義了虛函數fn( ),因此實現(xiàn)了多態(tài)的功能。/5_5.cpp#include class Basepublic:virtual void fn( )如果基類中的一個函數(例如

32、fn())被聲明為virtual,用基類的指針或引用來指明派生類對象并用該指針或引用來調用該函數,程序會根據對象的類型動態(tài)選擇相應的派生類的fn()函數。這就是動態(tài)綁定。如果用對象和圓點(.)運算符調用該函數(如der.fn( ))則是靜態(tài)綁定(即是在編譯時確定的)。 coutin base classendl;class Derive:public Basepublic:virtual void fn( )coutin derive classendl;在test( )函數中,b是基類Base的引用形參,Base類對象和Derive對象都可以作為參數傳遞給b。而fn( )是Base類的虛函數

33、,所以b.fn()的調用要到運行時才能確定調用的是基類的fn( )還是派生類的fn( )。;void test(Base &b)b.fn();void main()由于函數fn( )標識為虛函數,編譯時系統(tǒng)遇到b.fn( )后,會將其作為后期綁定處理,保證在運行時確定調用的是基類的fn( ),還是派生類的fn( )。Base b;Derive der;coutcalling test(b)endl;test(b);coutcalling test(der)endl;test(der);程序運行結果為: calling test(b) in base class calling test(der

34、) in derive class編譯通常是在前期綁定狀態(tài)下工作的,只有對于虛函數,才把它作為后期綁定來實現(xiàn)。多態(tài)性增加了一些數據存儲和執(zhí)行指令的開銷,但是在多數情況下,這種額外的開銷不會對程序運行效率有大的影響。因此,在類中應將成員函數盡可能設為虛函數。綁定是指一個計算機程序自身彼此關聯(lián)的過程。按照綁定所進行的階段不同,可分為前期綁定和后期綁定。又稱為靜態(tài)綁定和動態(tài)綁定。前期綁定是指綁定工作出現(xiàn)在編譯鏈接階段,這種綁定過程在程序開始運行之前已經完成。也叫做靜態(tài)聯(lián)編或靜態(tài)綁定。后期綁定是指編譯程序在編譯階段不能確定將要調用的函數,只有在程序運行時才能確定要調用的函數,為此要求綁定工作在程序運行

35、時進行。這種在程序運行時進行的綁定工作稱為后期綁定,也叫做動態(tài)聯(lián)編或動態(tài)綁定。5.4.2 虛擬函數虛擬函數(virtual function)指的是某個函數在基類中被聲明為virtual,而在派生類中又重新定義了這個函數。虛擬函數是動態(tài)綁定的基礎。虛擬函數是成員函數,而且是非靜態(tài)的成員函數。聲明虛擬函數的語法形式為:virtual 函數類型 函數名稱( )其中virtual是聲明虛擬函數的關鍵字。虛擬函數簡稱為虛函數。如果一個類的成員函數聲明為虛函數,這就意味著該成員函數可能在它的派生類中有不同的實現(xiàn)。動態(tài)綁定只能通過指針或者引用標識對象來操作虛函數,當聲明一個指向基類的指針時,該指針也適用于

36、相應的派生類。如果使用一般類型標識對象操作虛函數,則將采用靜態(tài)綁定方式調用虛函數。例如:/5_6.cpp#include class basepublic:virtual void f1()coutf1 function of baseendl;virtual void f2()coutf2 function of baseendl;virtual void f3()coutf3 function of baseendl;void f4() /一般成員函數coutf4 function of baseendl;class subclass:public basepublic:virtual v

37、oid f1() /多態(tài)coutf1 function of subclassendl;virtual void f2(int x) /參數不同無法實現(xiàn)多態(tài)coutf2 function of subclassendl;virtual void f4() /在基類中沒有被聲明虛函數,不能實現(xiàn)多態(tài)coutf4 function of subclassf1();p-f2();p-f3();p-f4(); p=≻p-f1();p-f2();p-f3();/在子類subclass中沒有重載父類base的成員函數f3(),不能實現(xiàn)多態(tài)p-f4();程序的運行結果是:f1 function of b

38、asef2 function of basef3 function of basef4 function of basef1 function of subclassf2 function of basef3 function of basef4 function of base由上面的程序可以看出:(1) 虛函數在基類與派生類中的聲明(包括函數名、返回值類型和參數列表)必須一樣才能實現(xiàn)多態(tài)。(2) 只有類的成員函數才能聲明為虛函數。(3) 內聯(lián)函數、構造函數(調用時產生)、靜態(tài)成員函數(不屬于對象)不能聲明為虛函數。(4) 對虛函數調用的解釋取決于調用它的對象。(5) 對非虛函數調用的解釋取

39、決于調用它的指針或引用的類型。5.4.3 純虛函數和抽象類純虛函數是一種特殊的虛函數,它的定義格式是:virtual ()=0;在許多情況下,在基類中不能對虛函數給出有意義的實現(xiàn),而把它聲明為純虛函數,實現(xiàn)留給基類的派生類做。抽象類:帶有純虛函數的類是抽象類。抽象類是一種特殊的類,它是為了抽象和設計的目的而建立的,抽象類的作用是將子類組織在一個繼承層次結構中,給子類提供一個公共的根。抽象類的特點: 抽象類只能做其他類的基類,不能建立抽象類的對象。 抽象類不能用作參數類型、函數返回類型。 抽象類可以聲明指針和引用,指針指向它的派生類,實現(xiàn)多態(tài)性。例如,下面的程序定義了一個抽象類shape,該類中

40、包含一個純虛函數view()的聲明,在它的派生類rect(長方形)、square()正方形和circle(圓)中分別對純虛函數view()定義了不同的實現(xiàn)。/5_7.cpp#include const double pi=3.1415;class shape /抽象類protected:double x,y;public:void setvalue(int i,int j=0)x=i;y=j;virtual void view( )=0; /純虛函數;class rect:public shapepublic:void view()cout長方形面積是:x*yendl;class square

41、:public shapepublic:void view()cout正方形面積是:x*xendl;class circle:public shapepublic:void view()cout圓面積是:pi*x*xsetvalue(3 , 5);p0-view();p1=&s;p1-setvalue(3);p1-view();p2=&c;p2-setvalue(3);p2-view();程序運行結果如下: 長方形面積是:15 正方形面積是:9 圓面積是:28.27355.5 虛擬析構函數在析構函數前面加上virtual關鍵字,則析構函數被聲明為虛擬析構函數,虛擬析構函數的格式如下: clas

42、s virtual ( ); ;如果基類的析構函數被聲明為虛擬析構函數,那么它的派生類的析構函數也是虛擬的。虛擬析構函數的目的是在用delete運算符刪除對象時,能保證析構函數被正確地執(zhí)行。因為設置虛擬析構函數后,是用動態(tài)綁定的方式選擇析構函數的。例如,下面的程序在基類base中析構函數被定義為虛擬析構函數,派生類der的析構函數也被定義為虛擬析構函數。在main主函數中定義了一個基類的指針b,指向派生類的對象。/5_8.cpp#include class basepublic:virtual base() /聲明為虛擬析構函數coutdestructing baseendl;class de

43、r:public basepublic:char *ch;der(int i)ch=new chari;virtual der() /聲明為虛擬析構函數delete ch;coutdestructing derendl;void main()base *b=new der(20);delete b;程序的運行結果是: destructing der destructing base假如在基類base中析構函數不用虛函數,則輸出結果如下: destucting base5.6 上機指導5.6.1 類的繼承編寫一個統(tǒng)計動物種類的程序。目的:練習應用類的繼承,加深理解繼承的概念,在定義類時活學活用類

44、的繼承。首先聲明一個名為Animal(動物)的基類,然后再創(chuàng)建兩個派生類,一個是Mammal(哺乳動物),一個是Bird(鳥類)。子類Mammal含有子女數和讀取子女數的成員函數NumOffspring();子類Bird含有生蛋數、是否筑巢,以及取生蛋數的成員函數GetEggs( )。成員函數ShowMannal()和ShowBird()的功能是分別輸出各自的對象參數。程序的具體源代碼如下:/5_9.cpp#include #include #define FALSE 0#define TRUE 1/Animal類定義class Animalpublic:Animal(const char *s) /構造函數strn

溫馨提示

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

評論

0/150

提交評論