多態和虛函數詳解(讀書筆記)

一.多態性的概念: 1.多態:在面向對象方法中一般是這樣表述多態性的: 向不同的對象發送同一個消息,不同的對象在接收時會產生不同的行爲(即方法)。也可以說,多態性是“一個接口,多種方法”。 2.從系統實現的角度看,多態性分爲兩類: 靜態多態性和動態多態性。以前學過的函數重載和運算符重載實現的多態性屬於靜態多態性,動態多態性是通過虛函數(virtual function)實現的。 3.靜態多態性是指:在程序編譯時系統就能決定調用的是哪個函數,因此靜態多態性又稱編譯時的多態性。動態多態性是在程序運行過程中才動態地確定操作所針對的對象。它又稱運行時的多態性。 二.虛函數: 1.虛函數的作用是:允許在派生類中重新定義與基類同名的函數,並且可以通過基類指針或引用來訪問基類和派生類中的同名函數。 2.虛函數的使用方法: (1) 在基類用virtual聲明成員函數爲虛函數。這樣就可以在派生類中重新定義此函數,爲它賦予新的功能,並能方便地被調用。在類外定義虛函數時,不必再加virtual。 (2) 在派生類中重新定義此函數,要求函數名、函數類型、函數參數個數和類型全部與基類的虛函數相同,並根據派生類的需要重新定義函數體。C++規定,當一個成員函數被聲明爲虛函數後,其派生類中的同名函數都自動成爲虛函數。 (3) 定義一個指向基類對象的指針變量,並使它指向同一類族中需要調用該函數的對象。 (4) 通過該指針變量調用此虛函數,此時調用的就是指針變量指向的對象的同名函數。 3.什麼情況下應當聲明虛函數 (1) 首先看成員函數所在的類是否會作爲基類。然後看成員函數在類的繼承後有無可能被更改功能,如果希望更改其功能的,一般應該將它聲明爲虛函數。 (2) 如果成員函數在類被繼承後功能不需修改,或派生類用不到該函數,則不要把它聲明爲虛函數。不要僅僅考慮到要作爲基類而把類中的所有成員函數都聲明爲虛函數。 (3) 應考慮對成員函數的調用是通過對象名還是通過基類指針或引用去訪問,如果是通過基類指針或引用去訪問的,則應當聲明爲虛函數。 需要說明的是: 使用虛函數,系統要有一定的空間開銷。當一個類帶有虛函數時,編譯系統會爲該類構造一個虛函數表(virtual function table,簡稱vtable),它是一個指針數組,存放每個虛函數的入口地址。系統在進行動態關聯時的時間開銷是很少的,因此,多態性是高效的。 4.虛函數與重載的區別: 以前介紹的函數重載處理的是同一層次上的同名函數問題,而虛函數處理的是不同派生層次上的同名函數問題,前者是橫向重載,後者可以理解爲縱向重載。但與重載不同的是: 同一類族的虛函數的首部是相同的,而函數重載時函數的首部是不同的(參數個數或類型不同)。 5.虛析構函數: (1)析構函數的作用是在對象撤銷之前做必要的“清理現場”的工作。當派生類的對象從內存中撤銷時一般先調用派生類的析構函數,然後再調用基類的析構函數。但是用new 和delete建立和釋放對象的時候,系統只執行基類的析構函數,而不會執行派生類的析構函數。 (2)如果將基類的析構函數聲明爲虛函數時,由該基類所派生的所有派生類的析構函數也都自動成爲虛函數,即使派生類的析構函數與基類的析構函數名字不相同。 (3)最好把基類的析構函數聲明爲虛函數。這將使所有派生類的析構函數自動成爲虛函數。這樣,如果程序中顯式地用了delete運算符準備刪除一個對象,而delete運算符的操作對象用了指向派生類對象的基類指針,則系統會調用相應類的析構函數。說明:構造函數不能聲明爲虛函數。 三.純虛函數與抽象類: 1.純虛函數: (1)定義: 純虛函數是在聲明虛函數時被“初始化”爲0的函數。聲明純虛函數的一般形式是:virtual 函數類型 函數名 (參數表列) =0; 也就如:virtual float area( ) const =0;//純虛函數 注意: ①純虛函數沒有函數體;②最後面的“=0”並不表示函數返回值爲0,它只起形式上的作用,告訴編譯系統“這是純虛函數”; ③這是一個聲明語句,最後應有分號。 (2)作用:純虛函數的作用是在基類中爲其派生類保留一個函數的名字,以便派生類根據需要對它進行定義。如果在基類中沒有保留函數名字,則無法實現多態性。 2.抽象類: (1)定義:不用來定義對象而只作爲一種基本類型用作繼承的類,稱爲抽象類(abstract class),由於它常用作基類,通常稱爲抽象基類(abstract base class)。 (2)凡是包含純虛函數的類都是抽象類。因爲純虛函數是不能被調用的,包含純虛函數的類是無法建立對象的。抽象類的作用是作爲一個類族的共同基類,或者說,爲一個類族提供一個公共接口。 (3)如果在派生類中沒有對所有純虛函數進行定義,則此派生類仍然是抽象類,不能用來定義對象。 (4)雖然抽象類不能定義對象(或者說抽象類不能實例化),但是可以定義指向抽象類數據的指針變量。當派生類成爲具體類之後,就可以用這種指針指向派生類對象,然後通過該指針調用虛函數,實現多態性的操作。 (5)在類的層次結構中,頂層或最上面的幾層可以是抽象基類。抽象基類體現了本類族中各類的共性,把各類中共有的成員函數集中在抽象基類中聲明。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章