C++程序設計與實踐:10-虛函數(shù)和多態(tài)性_第1頁
C++程序設計與實踐:10-虛函數(shù)和多態(tài)性_第2頁
C++程序設計與實踐:10-虛函數(shù)和多態(tài)性_第3頁
C++程序設計與實踐:10-虛函數(shù)和多態(tài)性_第4頁
C++程序設計與實踐:10-虛函數(shù)和多態(tài)性_第5頁
已閱讀5頁,還剩25頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第九章 虛函數(shù)和多態(tài)性本章要點多態(tài)性的概念。多態(tài)性是指一種界面,多種實現(xiàn)。多態(tài)性分為靜態(tài)多態(tài)性和動態(tài)多態(tài)性。虛函數(shù)。函數(shù)重載是靜態(tài)多態(tài)性的具體示例,虛函數(shù)是動態(tài)多態(tài)性的具體示例。純虛函數(shù)和抽象類。純虛函數(shù)是在基類中說明的虛函數(shù),在基類中沒有定義,要求任何派生類都必須定義自己的版本。如果一個類至少有一個純虛函數(shù),則該類稱為抽象類。9.1 問題引入在完成了第八章中的所有類型設計和編碼后,可以編寫這樣的測試代碼:期望得到如下輸出:Parallelogram: area = 35Rectangle: area = 72Diamond: area = 15Square: area = 49int mai

2、n()Parallelogram para(Parallelogram, 5, 7);Rectangle rect(Rectangle, 6, 12);Diamond diam(Diamond, 3, 5);Square sqr(Square, 7); List list; list += ¶list += ▭list += ⋄list += &sqr; list.traverse(access); return 0;void List:traverse(ACCESSFUN f) Node *p = head; while (p != NULL) f(p-quad

3、); p = p-next; void access(QUADPTR quad)cout what() : area = area () area()這樣的成員函數(shù)調用能取代基類的同名函數(shù),那么就一定要使派生類的area()覆蓋(override)基類的同名函數(shù)9.3.1 虛函數(shù)的概念和特性1. 虛函數(shù)的概念要使派生類的成員函數(shù)覆蓋基類的同名成員,那么必須將基類的成員函數(shù)說明成是虛函數(shù),其語法如下:class 類名public:virtual 成員函數(shù)名(參數(shù)列表);(ex9-1關鍵字virtual明確地告訴編譯器:該類派生類中的同名成員函數(shù)將覆蓋基類已定義的函數(shù)多態(tài)類多態(tài)類(polymorp

4、hic class)一個聲明了虛函數(shù),或者其祖先類中包含了虛函數(shù)的類在繼承樹上,每一個設計良好(well-formed)的多態(tài)類都有一個最終覆蓋函數(shù)(final overrider)如果沒有,那么該派生類將從其祖先那里繼承過來。然而,這并不是一種好的設計,而是病態(tài)的(ill-formed)對虛成員的訪問在后代中,祖先的虛成員仍然是存在的、可訪問的例:double Parallelogram:area() const Quadrangle:area();return width * height; 但這種訪問只能在派生類中進行。虛特性一旦成員函數(shù)被說明成虛的,那么我們稱該函數(shù)具有“虛特性”特點:

5、虛特性必須賦予類的成員函數(shù)。不能將虛函數(shù)說明為全局(非成員的)函數(shù),也不能說明為靜態(tài)成員函數(shù)。不能將友元說明為虛函數(shù),但虛函數(shù)可以是另一個類的友元。虛特性的繼承虛特性是可以被繼承的。在繼承樹上,一旦基類中的某個函數(shù)被聲明成是虛的,那么其所有后代中原型相同的函數(shù)都將是虛的正如上例中的area(),后代中的該函數(shù)可以不必使用關鍵字virtual,因為它自動成為了虛函數(shù)。提問:如果派生類中重載了一個原型不同的函數(shù),那么這個函數(shù)將會怎樣來影響虛特性的遺傳呢?(ex9-2)虛析構函數(shù)類的析構函數(shù)可以被說明成是虛函數(shù),并且也應該是虛的。而類的構造函數(shù)不能為虛函數(shù)。提問:問什么類的析構函數(shù)應該是虛的?提示:

6、考慮用new創(chuàng)建的自由對象。例(ex9-3)解決問題的方法有兩個: 通過強制類型轉換將指針p轉換為派生類指針,具體做法如下:delete (Parallelogram *)(p); 將Quadrangle類的析構函數(shù)說明成是虛的:virtual Quadrangle() 9.3.2 虛函數(shù)的實現(xiàn)機制例9-4 含有虛函數(shù)的類的大小class QuadrangleWithNoVirtualprotected: int a;public: double area()return -1.0;virtual虛表編譯器首先要對每個包含虛函數(shù)的類創(chuàng)建一個虛表(VTABLE)。在VTABLE中,編譯器放置該類

7、的虛函數(shù)地址。在每個帶有虛函數(shù)的對象中,編譯器秘密地設置一個指針( 就 是 多 出 的 那 部 分 數(shù) 據(jù) ) , 稱 為 “ 虛 指 針(vpointer/VPTR)”,指向這個對象的VTABLE。Quadrangle對象VPTR&area()VTABLEParallelogram對象VPTR&area()VTABLEQuadrangle類型的指針為每個類設置VTABLE、初始化VPTR、為虛函數(shù)調用插入代碼,所有這些都是自動完成的虛函數(shù)應用場景那么,一個成員函數(shù)什么時候需要聲明為虛函數(shù)呢?主要考慮以下幾點: 首先考慮成員函數(shù)所在的類是否會做為基類。然后看成員函數(shù)在類的繼承后有無功能被修改?

8、如果希望修改其功能,一般將它聲明為虛函數(shù)。 如果成員函數(shù)在類被繼承之后功能不需要修改,或派生類中用不到該函數(shù),則不要把它聲明為虛函數(shù)。 應當考慮對成員函數(shù)的調用是通過對象名還是基類指針或引用去訪問。如果通過基類指針或引用去訪問,則聲明為虛函數(shù)。 如果希望通過基類指針或者引用訪問派生類成員函數(shù),但基類功能比較抽象或者不能確定功能,可以將基類定義為抽象類,即只定義函數(shù)名字,沒有函數(shù)體,具體功能由派生類添加。9.4 純虛函數(shù)和抽象類純虛(pure virtual)函數(shù)的引入基類往往表示一些抽象的概念。例如,Quadrangle是一個基類,它表示一個沒有具象的四邊形,從Quadrangle可以派生出其

9、它具體的形體類。在這棵繼承樹上,基類Quadrangle體現(xiàn)了一個抽象的概念在這種情況下,基類的有些虛函數(shù)沒有定義是很正常的,但是要求派生類必須重定義這些虛函數(shù),以使派生類有意義純虛函數(shù)純虛函數(shù)是一個在基類中說明的虛函數(shù),它在該基類中沒有定義,要求任何派生類都必須定義自己的版本。為說明一個純虛函數(shù),使用下列一般形式:class Quadranglepublic:virtual double area() = 0;在類的構造和析構函數(shù)中可以調用普通成員函數(shù)甚至普通虛成員,但如果直接或間接調用了純虛成員,那么該類的行為是不可預知的。因此,應該杜絕這類行為。抽象類如果一個類至少有一個純虛函數(shù),那么就

10、稱該類為“抽象類(abstract class) ”假設類A是一個抽象類,那么它的特點是:不能創(chuàng)建抽象類A的對象。抽象類A只能用作其它類的基類。例如:A obj; /errorclass B : public A ; /OK抽象類 在抽象類的派生類中,如果純虛函數(shù)的最終覆蓋函數(shù)仍是一個純虛函數(shù)(即仍未提供一個函數(shù)體),那么該派生類仍是一個抽象類。抽象類 抽象類不能用作函數(shù)的參數(shù)類型、返回類型。例如:int f(A a); /errorA g() ; /error 可以聲明抽象類的指針和引用,它們可以作為函數(shù)的參數(shù)或返回類型。例如:A &r = obj, *p = &obj; /OKint h(A *, A&); /OKA* k(); /OKA& s(); /OK抽象類 抽象類不能作為顯式轉換的類型。例如:class Cpublic:operator A() ;抽象類提問1:在類中聲明了純虛函數(shù)后,可以為該函數(shù)定義函數(shù)體嗎?答案是肯定的。例如:class Quadranglepublic:virtual double area() = 0;double Quadrangle

溫馨提示

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

評論

0/150

提交評論