C++語言程序設計基礎知識_第1頁
C++語言程序設計基礎知識_第2頁
C++語言程序設計基礎知識_第3頁
免費預覽已結束,剩余17頁可下載查看

下載本文檔

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

文檔簡介

1、精品文檔第12章 面向對象程序設計與 C+基礎程序設計語言是編寫程序的工具,程序設計語言的發展反映了程序設計方法的演變過 程。隨著計算機技術的日新月異,要求軟件具有良好的可重用性和可擴展性,這就導致程序設計方法從結構化程序設計方式轉變到面向對象程序設計方式。C語言能夠很好地支持結構化程序設計,C+不僅兼容C,同時具有面向對象的特征,因此充分支持面向對象程序設計。12.1面向對象程序設計的基本概念面向對象技術變革了軟件設計的傳統方法。解決結構化程序設計不足的方法就是限制數據的存取權限,面向對象程序設計把數據和使用此數據的過程封裝成一個類(類可看成是一個基本數據類型)。數據的封裝和隱藏一方面使得內

2、部數據不被破壞,另一方面程序具有良 好的可讀性和相對獨立性。類的繼承機制不僅提高了代碼的可重用性,降低了軟件開發難度和開發周期,同時程序的修改變得容易,軟件結構更加穩定,軟件的可維護性大大提高。 面向對象軟件系統由類的層次結構組成,類的具體實例叫做對象, 對象之間通過彼此的聯系,共同實現程序的功能。如圖12-1所示。類的層次結構圖12-1面向對象軟件系統面向對象程序設計方法提出一些全新的概念:對象、類、封裝、數據隱藏、繼承和多態 性等。多態性、數據封裝和繼承共同構筑了面向對象程序設計的三大機制。1. 類與對象屬性:顏色、進水量、洗滌指示操作方法:進水排冰洗滌氏甩干廠圖12-2洗衣機類示意圖面向

3、對象的方法學認為,客觀世界由對象組成, 對象有自己獨特的特征和行為,兩者密不可分。面向對象的軟件技術中,類是將不同類型的數據 和與這些數據相關的操作封裝在一起的集合體。對象 可看成類的具體實例。 圖12-2描述了洗衣機類。【例12-1】在現實世界中,鋼筆具有筆帽、筆體、筆尖、顏色、形狀等屬性特征,鋼筆具有的行為是書寫、灌鋼筆水。鋼筆作為一個整體,具 有獨特的屬性和行為,它們將被抽象成一個鋼筆類。這種自成一體性稱為封裝性。而你正在 使用的鋼筆,可以看成鋼筆類中的一個具體實例。我們不必關心鋼筆的內部結構及實現細節, 僅利用鋼筆對外提供的操作,即外部接口,就可以方便地使用鋼筆。【例12-2】 對于整

4、型類型的數據, 可以定義對它的四則運算, 這是整型數據具有的行為, 四則運算與整型數據封裝成一體,命名為“int類”。字符型運算和邏輯運算不可以訪問、修改int類中的數據,只有int類中定義的四則運算才能對其進行操作。顯然,我們也無需知道四則運算是如何定義的,int類對外界提供的操作接口是“ +”、“ “*”、“/”,可以直接利用這些接口實現整數的四則運算,這叫做數據的隱藏性。2. 數據的封裝和隱藏封裝強調的是數據和行為的自成一體性,也就是將數據和操作數據的函數代碼進行有機 的結合,形成“類”。封裝具有如下意義:1)面向對象的程序表現出強烈的可讀性和獨立性。2)程序不依賴數據結構的改變,具有良

5、好的可維護性。當數據結構改變時,只有類中 對數據進行操作的函數需要修改,程序的其他部分不受影響。3)對數據起到一定的保護作用。只有類中的函數才可以修改類中的私有數據。隱藏是指類把對數據的操作信息隱藏在內部,只提供對象對外的操作接口,用戶只能看見對象封裝接口上的信息, 這樣可以保護內部數據不被破壞,同時使用者使用起來非常方便,并可以容易地將其擴展成新的產品。3. 類的繼承類的繼承是指新的派生類可以繼承原有父類的全部數據和操作的機制,并可以在派生類中添加新的數據和操作方法。新的派生類又叫子類,原有父類又叫基類或超類。例如,想生產敞篷汽車不用從草圖開始,只需要對原有的產品添加新的敞篷功能,這樣就會快

6、速開發出一種新的產品。利用類的繼承特性,可以非常方便地產生一系列具有相似特征的對象。再看一個類繼承的例子。在小學,我們學過數的四則運算,到中學會進一步學到對數、 指數等運算,到大學將學到微積分等內容。我們每一次的進步都將繼承已學過的知識,在已有的基礎上不斷擴充新的知識。4. 消息對象之間通過消息相互聯系,也是通過消息讓某一個對象完成一定的功能。例如,給洗衣機對象發洗滌的操作信號,洗衣機就會執行洗滌的功能。在面向對象的程序設計中,消息名就是在對象中定義的操作(或稱方法),給對象發消息,就是讓對象執行某一操作,使對象具有行為的能力。如圖12-3所示。發消息邊長、頂點執行操作1求面積求周長求面積求面

7、積在C+中的表示:A ?求面積(邊長,頂點坐標)圖 12-3消息機制5. 多態性多態性表示同一種東西有多種形態。例如,與對方通信,這個動作將有多種表現形態, 如采用寫信的方式、打電話、發電報、發電子郵件等。在面向對象的程序設計中,多態性是指同一個(或相似的)操作作用于不同的對象上可以有不同的獨特行為,比如 add操作,作用在實數對象上,表現為兩個實數相加,作用在虛數對象上,表現為兩個虛數相加。面向對象的C+語言允許程序員給不同的對象發同一消息,軟件系統會做出決策,即到 底執行什么動作。在靜態(編譯或連接)時就可以分辨的,可通過函數重載實現;在運行時 才能分辨的,可通過虛函數實現。利用多態性,用

8、戶能夠發送一般形式的消息,而將所有的實現細節留給接收消息的對象。 這種高層次的抽象,使得多態性、數據封裝和繼承共同構筑了面向對象程序設計的三大機制。12.2面向對象程序設計語言 C+簡介C語言是一種受到廣泛重視和應用的面向過程編程的語言,它采用結構化程序設計技 術,即把復雜的模塊層層分解為一系列簡單模塊。人們側重于開發具有特定功能的函數,而 有些數據(特別是全局數據)在函數間可隨意傳遞。結構化程序設計語言無法處理高度復雜的程序,為了彌補結構化 C語言的不足,支持面向對象的程序設計的 C+語言應運而生。C+語言是一種混合性語言,保留了C語言的全部內容,同時擴展了 C語言所不具有的面向對象編程的機

9、制。C+在技術上與C完全兼容,但它具有與C語言完全不同的思維方式,即支持面向對象的程序設計思想,強調對數據進行封裝、保護等深入的維護,強調軟件的可擴展性、可修改性和可維護性。利用C+語言可以進行結構化編程,更重要的功能是進行面向對象的編程。12.2.1 C+ 程序結構本小節主要介紹兩個程序,一個是面向過程的 C+程序,見例12-3 ; 一個是面向對象的C+程序,見例12-4。通過這兩個實例,讀者可以對C+程序結構有個初步認識。【例12-3】以下程序實現輸入一個整數,求平方根并打印出來。/ 程序名:csqrt.cpp#include / 定義 cout()、cin()的頭文件#include /

10、 定義 sqrt()的頭文件using namespace std; / 使用命名空間 std void mai n()int x;coutx;/從鍵盤接收數據存入變量x中coutthe squart of nu mber=sqrt(x)e ndl; /輸出數據程序運行情況:in put nu mber 4the squart of nu mber=2說明:1) C+程序注釋行以“ / ”開頭,也可以使用C語言的注釋行方式。2) C+程序的后綴通常為 cpp。3) cout、cin是C+語言中增加的用來輸出和輸入的函數,分別代表標準的輸出設備對象和輸入設備對象。這兩個C+函數是在輸入輸出流頭文

11、件iostream內定義的。cout的使用形式:cout變量。4) endl操作符表示以后的輸出換行打印。5) C+標準程序庫中的所有標識符都被定義于一個名為std的namespace中,程序中第4行的使用,使得命名空間std內定義的所有C+標準庫函數名和標識符都有效,就好像它們被聲明為全局變量一樣。面向對象程序設計的首要任務是設計類,自頂向下利用演繹的思想,由抽象類派生 具體的子類;自底向上利用歸納的思想,由具體的子類歸納出具有共同特征的抽象的父類, 從而建立類的層次結構。再以類為模板創建不同的對象,然后協調這些對象共同工作。程 序的運行從main函數開始。【例12-4】編寫一個簡單的面向對

12、象的C+程序:設計一個 sample類,對整型數據進行管理,初始化并顯示對象。1:#in clude2:using n amespace std;3:class sample / create a class4: 5:private:6:int i;7:public:8:void in itial();9:void display();10:;11:void sample: in itial()/定義類的初始化成員函數12: i = 0;1314:void sample: display() /定義類的顯示成員函數15: cout i en dl;1617:void mai n()18: sa

13、mple A;/ 定義類sample的對象A19:A.i nitial();/給對象A發消息,進行對象的初始化20:cout Object A ,i =n.21:A.display();/給對象A發消息,顯示對象22: 運行結果:Object A ,i = 0說明:程序的第310行,用來聲明類sample。其中class是C+用來聲明類的關鍵字。該類 中定義了私有的整型數據成員i,以及公有成員函數initial() 和display。私有的整型數據成員i只能通過兩個公有成員函數進行初始化和顯示。程序的第1113行,用來定義類的公有成員函數initial(),其作用是初始化對象。程序的第1416

14、行,用來定義類的公有成員函數display(),其作用是顯示對象。程序的第1722行,是主函數,其中第18行用來定義一個具體的對象A,這意味著在內存為對象A分配空間,如圖12-4所示。第19行是給對象A發初始化的消息,對象A執行initial()函數,改變對象 A的狀態,如圖12-5所示。第21行是給對象A發顯示的消息,對象 A執行display()函數,顯示對象A的狀態。對C的補充對象A圖12-5對象A初始化12.2.2 C+1. 注釋行C+勺注釋有兩種類型:一種是沿用C語言的方法,采用“ /* ”和“ */ ”括起來進行注釋,另一種方法是只能用于C+的單行注釋,即從“ / ”開始,直到所在

15、行的行尾,所有字符都被作為注釋處理。2. C+ 的 cin 與 coutcout、cin是C+語言中增加的用來輸出和輸入的函數,分別代表輸出設備對象和輸入 設備對象。cout和cin函數的使用方式不隨變量的類型變化,這正是面向對象語言所追求 的。cout是代表標準輸出的流設備,如顯示屏。輸出操作必須配合操作符“”,表示把該操作符右邊的數據輸出到顯示屏上。cin是代表標準輸入的流設備,如輸入設備鍵盤。輸入操作必須配合操作符“”,代表從標準輸入設備讀取數據到內存。cin與cout定義在輸入輸出流頭文件iostream.h 中。3. 關鍵字const定義符號常量C+中的符號常量使用關鍵字const來

16、說明,其一般形式:con st類型說明符常量名=常量值或類型說明符con st常量名=常量值例如:定義一個 buf的常量。const int buf=512或int con st buf=5124. new和delete運算符C+噺增new和delete作為動態內存分配和釋放的操作符,用來增強C語言中原有的函數malloc和free,提高了內存管理的靈活性。例如:int *p; /定義指向整數的指針變量p=new in t;/動態申請存放整數的內存空間delete p; / 釋放p指向的動態內存空間5. 引用作為函數參數C+新增了引用,它使函數調用變得清晰、簡單,參數傳遞效率更高。同時,將引用

17、作 為函數參數給編程帶來了很大的靈活性。引用可看成某個目標變量的別名, 對引用的操作,實際上就是對目標變量的操作,引用與目標變量完全對應。 一旦用目標變量給引用賦初值,引用就被維系在該目標變量上,即引用不會再與其他目標變量建立聯系。引用不能是空,與此相反,指針變量可以為空。聲明并初始化引用的一般格式:數據類型&引用名=目標變量; 其中,“數據類型”是定義目標變量的類型,而“數據類型&”是用來聲明引用的。例如:int m;int& kk=m; / 聲明kk是對整型變量 m的引用m=4;kk=1O; 此時目標變量 m的值通過引用改為 10 【例12-5】引用作為函數參數。#in clude usi

18、ng n amespace std;void swap(int&, int&);/聲明形參是引用類型void mai n()int x=10, y=20;coutbefore swap, x=x, y=ye ndl;swap(x,y);/函數調用,實際傳遞的是實參地址coutafter swap, x=x, y=ye ndl;void swap(i nt& xx, i nt& yy) /形參是引用類型int temp;temp=xx;xx=yy;yy=temp;運行結果:before swap, x=10, y=20after swap, x=20, y=10該程序通過調用函數swap(),交

19、換主函數中變量 x和y的值。在主函數中,調用函數 swap(x,y)時,實參看起來是值傳遞,其實傳遞的是實參地址。在定義函數swap()時,形參是引用類型,這就使得引用xx與目標實參x的地址維系在一起, 引用yy與目標實參y的地址維系在一起。在執行函數swap()時,對引用xx與yy的操作,實際上就是對x與y的操作。【例12-6】指針作為參數實現與上述程序同樣的功能。#in clude using n amespace std;void swap( int *, int * );/聲明形參是指針類型void mai n()int x=10, y=20;coutbefore swap, x=x,

20、 y=ye ndl;swap( &x, &y); /函數調用,傳遞實參的地址coutafter swap, x=x, y=ye ndl;void swap(int * xx, int * yy)/ 形參是指針類型int temp;temp=*xx;*xx=*yy;*yy=temp;運行結果:before swap, x=10, y=20after swap, x=20, y=10該程序在調用函數 swap()時,實參是&x與&y,表明將把x與y的地址傳入到形參中, 而形參必須聲明為指針類型,接收傳進來的地址。在函數swap()的定義體中,*xx是指針變量xx所指向的變量,實際上就是主函數中的

21、變量x; *yy是指針變量yy所指向的變量,實際上就是主函數中的變量通過上述兩個程序風格的對比,形參是引用時,函數體簡練、清晰、可讀性好。而形參 是指針類型時,函數體內過多的指針運算降低了程序的可讀性,容易產生錯誤。當形參是引用時,傳遞的是實參本身(通過傳遞地址的形式),因此當函數被調用時,在函數作用域內,并沒有建立實參的副本,這種機制大大提高了效率,節省了空間。比如,若要傳遞的參數是結構或類這樣較大的數據類型,顯然不希望復制副本,以提高參數傳遞的效率,并節省內存。必須當形參既不是引用也不是指針變量時,參數傳遞屬于值傳遞,此時若函數被調用,在函數作用域建立實參的副本,這通常以時間和空間的浪費為

22、代價。6. 函數返回類型是引用而函而當函數返回類型不是引用時,實際上是在內存中開辟臨時空間存放函數返回的值,數返回類型是引用時,不需要這樣一個中間過程,即不需要產生臨時變量以存放返回值,直接把返回值傳回到主函數中,從而大大提高程序執行的效率,同樣也節省了空間。 注意不要返回不在主函數作用域內的變量或對象的引用。【例12-7】返回引用類型的應用。#in elude using n amespaee std; in t large;int& max(x,y) large的引用/返回變量large=(xy)?x:y; return large; void mai n()large的引用,使得larg

23、e的值直接傳給 f與目標large維系在一起返回變量/引用int d=max(10,46); / int& f=max(10,56);7. 內聯函數C+編譯程序為了減少函數調用的開銷,C+引入了內聯函數。內聯函數的功能是強迫直接使用函數體代碼替換調用語句,以提高程序的運行速度。內聯函數定義的一般形式:inline函數類型函數名(形參表)函數體通常只將規如果在類的聲明中直接給出成員函數的定義,該成員函數默認為內聯函數。模較小又使用頻繁的函數設計為內聯函數。8. 帶默認形參值的函數C+允許定義帶多個默認形參值的函數。例如,設函數原型聲明情況如下:int eha nge(i nt x=10, int

24、 y=20);則函數調用情況如下:change(40); / 形參y采用默認值20change();/ 形參x和y都采用默認值1223 C+ 中的類1. 類的定義類是由成員組成的,包括一組數據成員和成員函數,其定義的一般形式:class 類名private:私有數據和成員函數public :公有數據和成員函數protected :保護數據和成員函數;類的名稱由關鍵字 class開始,類的定義體夾在一對花括號中,后面可以跟分號, 或一組屬于該類的對象。類內的一組成員變量和成員函數可以有以下三種類型:私有數據類型(private )、保護數據類型(protected )、公有數據類型(public

25、 )。如果用private來說明類的數據和成員函數,則意味著它們只能被該類中定義的成員函數和 友元函數訪問。通常數據默認為私有類型,私有類型的保留字private可以省略。如果用protected 來說明類的數據和成員函數,則意味著它們只能被該類中的成員函 數、友元函數、該類的派生類中的成員函數所訪問。如果用public來說明類的數據和成員函數,意味著可以在類的外部(不通過類的成員 函數,如主函數)存取數據。類中的公有成員函數提供了該類對外的接口,即通過公有成員函數,才可以訪問類的私有數據。2. 類的成員類的數據成員不僅包含普通的數據變量,而且還可以包含其他類的對象。類是一種新的數據類型,而對

26、象可看成是由類定義的變量。類的成員函數對類內的數據成員施加操作,實現類的特定功能。若成員函數很小,可以在類內定義,反之,一般在類外定義。數據成員通常定義為私有或保護類型,以便隱藏和保護數據。成員函數通常定義為公有類型,目的是提供對外的接口,以便能夠對類訪問。為了在類外定義成員函數,必須指出該成員函數是屬于哪個類的,C+中引入了一個符號“:”,稱為作用域運算符。在類外定義成員函數的一般形式:函數返回類型類名:成員函數名(形參表)函數體3. 對象的定義類是對具有相同屬性和行為的一組相似對象的抽象,而對象是類的具體實例。類可看成是一個抽象的數據類型,而類的對象就是屬于類的一個具體變量。類不是一個占有

27、內存的實體,但對象卻是。創建類中的對象,就是在內存中創建具體的對象,其含義就是在內存中為類中的數據分配存儲空間,它們是對象的具體體現。通常在子函數中、主函數中以及函數的前面采用如下方式定義對象: 類名對象名;這種方式使得對象如普通變量一樣,具有一定的作用域(生存期)。4. 類成員的使用類中的成員,包括數據成員和成員函數。有了對象,若想使用類中的公有成員,可采用以下形式:對象名.公有數據成員對象名公有成員函數例如,m.input();是指給對象m發消息input(),對象m執行input()函數。注意類中的私有數據只能通過該類的成員函數進行訪問,類中的保護數據可被該類的成員函數以及該類的派生類的

28、成員函數或友元函數所訪問。5. 類成員的初始化(1)數據成員初始化類中公有數據成員可像普通變量一樣使用,可在定義對象后,在需要時賦初值。假設有一公有數據num,對象名為A,則用如下方式初始化:A.nu m=10; / 公有數據可以直接使用類中的私有或保護數據只能在類及派生類中的成員函數或友元函數中使用,所以不允許直接引用類的實例對象中的私有或保護數據成員。如例12-6中,類sample的實例對象為A,由于類sample中的i是私有數據成員,所 以不可以采用如下方式賦值:A.i=5; / 錯誤,私有數據不可以直接引用對私有數據i的初始化是通過類 sample中的初始化成員函數實現的。對象的初始化

29、對私有或保護數據成員的初始化可通過對象的初始化實現。對象的初始化就是給對象數據賦初值。對象的初始化一般有兩種方式:一是通過類中的普通成員函數,二是通過類中的特殊成員函數。而最通用的是通過類中的特殊成員函數,即構造函數來實現。在12.2.4節例12-10的主函數中,首先定義類DATE的實例對象 m以便給對象數據分配存儲單元(參看圖 12-10),由于構造函數的特殊性,它可以在定義類中的對象的同時, 由系統自動調用,初始化對象的數據。普通的初始化成員函數,可用下面的方式初始化類的對象:A.i nitial(); / 參看 12.2.1 節例 12-6此時對象A調用成員函數initial()響應消息

30、,該函數給對象A的私有數據賦初值。12.2.4 C+ 中的構造函數和析構函數1. 構造函數在C+中通常自動初始化對象的數據。為了做到這一點,可以定義一個特殊的成員函數,它的名字與類名相同,稱為構造函數。構造函數的作用是在對象被創建時使用特定的值構造 對象,或者說將對象初始化為一個特定的狀態。當我們定義屬于類的對象時,系統就自動執行構造函數,初始化具體的對象。如果程序沒有聲明構造函數,系統會自動地為程序設置一個,此構造函數什么也不做。 對象在創建時只是被分配空間,具體的初值只能由用戶定義的初始化函數來實現。關于構造函數,給出以下幾點說明:1) 構造函數與類名相同。2) 構造函數沒有返回類型,也不

31、能是void類型。3) 構造函數不能被隨意調用,由系統自動調用。4) 構造函數可以重載,可以帶默認形參,可以是內聯函數。5) 構造函數可以帶參數也可不帶參數,不帶參數的構造函數稱為默認的構造函數。2. 析構函數此外,C+還提供了一種特殊的成員函數,叫做析構函數。當對象被取消時,系統首先 會自動調用類的析構函數,然后撤銷對象(釋放對象所占用的存儲空間)。如果程序中沒有聲明析構函數,則系統會自動為程序設置一個析構函數。如果用new()函數動態分配對象,當動態對象被取消時,系統會調用析構函數。因此,通常在析構函數中設置delete()函數就會自動撤銷動態對象。關于析構函數,給出以下幾點說明:1) 析

32、構函數的名稱與類名相同,但前面加符號“”。2) 析構函數沒有返回類型,也不能是void類型,沒有參數。3) 析構函數由系統自動調用,不能隨意調用,不能重載。4) 一個類中只能有一個析構函數。5) 基類的析構函數可以是虛函數,以便系統調用派生類析構函數,撤銷其對象。【例12-8】編寫一個日期類 DATE對年、月、日進行管理,能響應詢問日期及判斷是否閏年。#in clude using n amespace std;class DATE / 定義 DATE類int year; /定義類的私有數據,private 可省略int mon th;int day;public:DATE() II定義類的構

33、造成員函數,初始化對象 year= mon th=day=O; int leapyear()II定義判斷閏年的成員函數 if(year%4=0 & year %100 !=0) | year%4OO=O) return 1;else return 0;void input()II定義輸入數據的成員函數,并對輸入的數據進行分析判斷 int days=31,28,31,30,31,30,30,31,30,31,30,31;int cc;while(1) cout year month day;if(mo nth = 1 & mon th 0 & day =cc)break;void disp()

34、/定義顯示數據的成員函數 cout Y= year M= month D= day endl; ;/類聲明結束void main()/定義主函數,實現類的實例化,并給對象發消息 DATE m; /定義對象m,系統自動調用構造函數初始化對象m.i nput();/給對象m發消息in put,使對象的數據發生變化if(m.leapyear()/給對象發消息,判斷是否閏年cout Leap year!;elsecout 對象 Aday程序運行情況:In put Year Mon th Day: 2006 11 8Not leap year! Y=2006 M=11 D=8說明:當在主函數中定義對象m

35、后,具體的對象就存在了,如圖12-6所示。由于 C+系統可以在定義對象時自動調用 構造函數初始化,所以一開始對象m的數據被初始化為0。圖12-6實例化類中的對象【例12-9】帶有參數的構造函數,以及析構函數程序。#in clude using n amespace std;class Exampleint i;public:Example( int x);/帶參數的構造函數Example()i=0;/不帶參數的默認的構造函數void display();Example() coutDestroyed!endl;/ 析構函數;Example:Example(i nt x) i=x; void E

36、xample:display() coutI=ie ndl;void mai n()Example A(7);/定義對象A,系統自動調用帶參數的構造函數Example B; /定義對象B,系統自動調用默認的構造函數A. display();B. display();運行結果:1=71=0Destroyed! Destroyed!1225 C+ 中的繼承繼承是C+語言的一種重要機制,該機制實現了對原有類進行擴充,在此基礎上進行更 具體、更詳細的定義。通過繼承,新的派生類不僅可以自動獲得基類的所有成員變量和成員 函數(構造函數和私有函數除外),同時可定義新的成員變量和成員函數,來滿足新的軟件 需求

37、,進一步完善程序設計,提高軟件的重用性。1. 派生類在C+中,派生類從一個基類繼承的一般形式:class派生類名:public 基類名成員變量和成員函數聲明;其中,派生類名是新類名,public是最常用的繼承方式,本章主要介紹public繼承方式。此外,還有 private、protected 繼承方式,其特殊性可參考其他C+教材。注意1) 自動從基類繼承下來的所有成員變量和成員函數不在派生類的定義中出現,但若需要在派生類中重新定義基類的成員函數,就必須在派生類的聲明中列出來,并為其賦予一個新定義,這如同在派生類中新增一個成員函數。2) 任何其他類(包括派生類)的成員函數定義中,不能直接根據名

38、稱訪問繼承下來的基類 私有成員變量,但可以使用基類中定義的成員函數間接訪問基類的私有成員變量。3) 私有成員函數根本不會被繼承。【例12-10】派生類程序示例(基類是例12-8中定義的DATE類)。/定義派生類Holiday class Holiday: public DATE char name20;/派生類新增加的私有成員變量public:void set_name()/派生類新增成員函數 coutEnter Name of Holiday:;cin .getli ne(n ame,80,n); cin類中輸入字符串函數void input()/更新來自基類的成員函數 coutEnter

39、Date of Holidayendl;DATE:input();/利用作用域調用基類的同名函數void disp()/更新來自基類的成員函數 DATE:disp();cout is n ame en dl; ;/定義主函數void main() /實現派生類的實例化,并給對象發消息 Holiday H;/定義派生類對象 HH.set_name(); / 給對象H發消息H.input();if(H.leapyear()/leap year()是繼承下來的公有成員函數cout Leap year!; elsecout Not leap year!;H.disp();程序運行情況:En ter N

40、ame of Holiday: May DayEnter Date of HolidayIn put Year Month Day: 2000 5 1Leap year!Y=2000 M=5 D=1year, mon th, dayn ame set_ name()in put() disp() leapyear()圖12-7派生類對象實體is May Day說明:派生類對象繼承下來基類的私有數據成員變量year,mo nth, day,并添加新的數據成員變量name派生類繼承基類的公有成員函數leapyear()(其代碼可重用,不需要重寫),并重新定義基類的公有成員函數disp()和inpu

41、t(),相當于新添加成員函數。另外,添加新的公有成員函數set_name()。如圖 12-7 所示。2. 基類的protected 成員不能在派生類的定義或實現中直接用名稱訪問基類的私有成員變量。但如果在基類中把成員變量和成員函數標記為protected 性質,則在其派生類(以及派生類的派生類)中不僅能繼承下來,且可以用名稱直接訪問,其性質保持為protected。而在其他任何類或函數中, 等同于用private 來標記。12.2.6 C+ 中的多態性、函數重載和虛函數多態性是面向對象程序設計的重要特征之一。繼承重點研究類與類的層次,多態則研究在不同層次的類中,同名成員函數的關系。所謂多態性就

42、是同樣的接口有不同的功能,同樣的消息被不同的對象接收時產生不同的行為。C+獲得多態性的方式是函數重載、運算符重載和利用虛函數來實現。1.函數重載普通函數、類的成員函數和友元函數都可以重載。函數重載是指函數名相同,但參數的類型和數量可以不同。系統根據其參數個數、參數類型,調用相應的函數,執行特定的功能。函數重載的意義在于能使用戶為某類操作起一個通用的名字,由編譯器在編譯時來確定選擇哪個函數來執行某一操作,從而降低了程序的復雜性。【例12-11】編寫兩個函數,分別求整型數和浮點型數的最大值。#in clude using n amespace std;int max(i nt a,i nt b);

43、double max(double a, double b);int max(i nt a, int b) return (ab? a:b); double max(double a, double b) return (ab? a:b);void mai n() coutmax(2,5) max(3.5,6.7)endl;運行結果:5 6.72.虛函數與純虛函數虛函數可以使程序在運行過程中動態地確定操作所針對的具體對象, 從而實現運行時的 多態性。聲明虛函數的方法是在基類中的成員函數原型前加上 virtual 。虛函數可以在一個 或多個派生類中重復定義, 但要求必須與基類中的函數原型完全相同

44、。 這時,無論在派生類 的相應成員函數前是否加上關鍵字 virtual ,都將視其為虛函數。在實際應用中,通常把基類中的虛函數定義為純虛函數, 即只在基類中聲明虛函數,而 不定義其函數體,將它的具體定義放到各個派生類中。 通過該基類指針或引用, 就可以在運 行時調用所有派生類的虛函數。純虛函數的聲明的語法形式如下:virtual 函數類型函數名(形參表)=0;【例12-12】設計一個圖形類,利用純虛函數實現運行時的多態性。要求:計算矩形和三角形的面積。分析:首先定義一個抽象的圖形類Shape,在類Shape下可以派生出多種具體的形狀。為了求這些圖形的面積,只需在類Shape中聲明一個純虛函數g

45、etArea(),而將計算具體形狀面積的定義放在其派生類中。#in clude using n amespace std;class Shapeprotected:double x,y;public:void set(double a, double b) x=a;y=b;virtual void getArea()=0;class Trian gle:public Shapepublic:void getArea() coutTriangle S=1/2*x*y=0.5*x*yendl; ;class Recta ngle:public Shapepublic:void getArea()

46、coutRecta ngle S=x*y= x*y set(3.4,6.7);/ 給對象 t 賦值p-getArea(); / 此時 p-getArea() 就調用 Triangle 的函數 getArea()p=&r;/p 指向 Rectangle 對象 rp-set(3.4,6.7);/ 給對象 r 賦值p-getArea(); / 此時 p-getArea() 就調用 Rectangle 的函數 getArea() 運行結果:Triangle S=1/2*3.4*6.7=11.39 Recta ngle S=3.4*6.7=22.78 小結C語言能夠很好地支持結構化程序設計,C+不僅兼容C,同時具有面向對象的特征,因此充分支持面向對象程序設計。結構化程序設計解決問題時,常常把復雜的問題分解為一系列數據和對數據進行處理的過程(或函數),因為數據沒有被“隱藏”在對它進行處理的過程中,這導致結構化程序設 計存在著巨大的隱患。面向對象技術變革了軟件設計的傳統方法。面向對象程序設計把數據和使用此數據的過程封裝成一個類。數據的封裝和隱藏一方面使得內部數據不被破壞,另一方面使程序具有良好的可讀性和相對獨立性。類的繼承機制不僅提高了代

溫馨提示

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

評論

0/150

提交評論