前一講的是運算子過載為類的友員函式。今天講的是屬於包含多型的虛函式。
一.虛函式的意義
在講賦值相容規則時給出了乙個程式例子,其中包含類base、child0和child1。在程式執行結果中我們看到,main函式中base型別的指標pbase,分別指向base、child0和child1類的物件時呼叫的show函式都是基類base的show函式。因為基類型別的指標指向派生類物件時,通過此指標只能訪問從基類繼承來的同名成員。這些在c++程式設計入門系列之四十三--賦值相容規則中已經分析過了。
但是如果我們希望通過指向派生類物件的基類指標,訪問派生類中的同名成員該怎麼辦呢?這就要用到虛函式了。我們在基類中將某個函式宣告為虛函式,就可以通過指向派生類物件的基類指標訪問派生類中的同名成員了。這樣使用某基類指標指向不同派生類的不同物件時,就可以發生不同的行為,也就實現了執行時的多型(編譯時並不知道呼叫的是哪個類的成員)。
虛函式是動態繫結的基礎。記住,虛函式是非靜態的成員函式,一定不能是靜態(static)的成員函式
。虛函式在以後我們進行軟體架構設計時會起到很關鍵的作用。程式設計入門時可能不會有這方面的意識,等熟練到一定程度你就會發現虛函式的強大。
二.一般虛函式成員的宣告和使用
一般的虛函式宣告形式為:
virtual 函式型別 函式名(形參表)
虛函式就是在類的宣告中用關鍵字virtual限定的成員函式。以上宣告形式是成員函式的實現也在類的宣告中的情況。如果成員函式的實現在類的宣告外給出時,則虛函式的宣告只能出現在類的成員函式宣告中,而不能在成員函式實現時出現,簡而言之,只能在此成員函式的宣告前加virtual修飾,而不能在它的實現前加。
總結下執行時多型的幾個條件:1.類之間要滿足賦值相容規則;2.要宣告虛函式;3.通過類的物件的指標、引用訪問虛函式或者通過類的成員函式呼叫虛函式。下面舉例說明下,大家通過這個例子來對照下這幾個條件。
此例是由賦值相容規則中的例子改進的。將基類中的函式show宣告為虛函式,程式其他部分不做任何修改。
#include
using namespace std;
class base // 基類base的宣告
// 虛成員函式show
};class child0 : public base // 類base的公有派生類child0的宣告
// 虛成員函式show
};class child1 : public child0 // 類child0的公有派生類child1的宣告
// 虛成員函式show
};void callshow(base *pbase) // 一般函式,引數為基類指標
int main()
程式執行結果:
base::show()
child0::show()
child1::show()
我們可以看出,僅僅是在base類中的show函式前加了virtual的修飾,執行結果就差了很多,這正是虛函式的美麗所在。
例程中,類base、child0和child1屬於同乙個類族,而且child0是由base公有派生的,child1是從child0公有派生的,所以滿足賦值相容規則,這就符合了執行時多型的第乙個條件。基類base的函式show宣告為了虛函式,這是第二個條件。在callshow函式中通過物件指標pbase來訪問虛函式show,這又滿足了第三個條件。這個動態繫結過程在執行時完成,實現了執行時的多型。這樣通過基類指標就可以訪問指向的不同派生類的物件的成員,這在軟體開發中不僅使**整齊簡潔,而且也大大提高了開發效率。
基類的成員函式宣告為虛函式以後,派生類中的同名函式可以加virtual修飾也可以不加。
三.虛析構函式
大家可能奇怪為什麼不先講虛建構函式,很簡單,因為不能宣告虛建構函式,而可以宣告虛析構函式。
多型是指不同的物件接收了同樣的訊息而導致完全不同的行為,它是針對物件而言的,虛函式是執行時多型的基礎,當然也是針對物件的,而建構函式是在物件生成之前呼叫的,即執行建構函式時還不存在物件,那麼虛建構函式也就沒有意義了。
析構函式用於在類的物件消亡時做一些清理工作,我們在基類中將析構函式宣告為虛函式後,其所有派生類的析構函式也都是虛函式,使用指標引用時可以動態繫結,實現執行時多型,通過基類型別的指標就可以呼叫派生類的析構函式對派生類的物件做清理工作。
前面講過,析構函式沒有返回值型別,沒有參數列,所以虛析構函式的宣告也比較簡單,形式如下:
virtual ~類名();
虛函式的內容就先講到這裡了,抽象度比較高。建議大家經常回來複習,以便更熟練的掌握,並服務於以後的程式架構的設計。謝謝大家,有問題還是歡迎到部落格來交流。
C 入門高階之6 多型性
1.多型是指同樣的訊息被不同型別的物件接收時導致不同的行為,訊息是指對類的成員函式的呼叫。2.多型的型別 過載多型,強制多型,包含多型和引數多型。3.多型的實現 分為編譯時的多型和執行時的多型 4.運算子過載 對已有的運算子賦予多重含義,使得同乙個運算子作用於不同型別資料時,導致不同的行為。5.運算...
多型性(C 程式設計指南)
1.使用new關鍵字時,呼叫的是新的類成員而不是已被替換的基類成員。這些基類成員稱為隱藏成員。如果將派生類的例項強制轉換為基類的例項,就仍然可以呼叫隱藏類成員.public class baseclass public int workfield public int workproperty pu...
C C 程式設計(三) C 多型性
c 程式語言是一款應用廣泛,支援多種程式設計的計算機程式語言。我們今天就會為大家詳細介紹其中c 多型性的一些基本知識,以方便大家在學習過程中對此能夠有乙個充分的掌握。多型性可以簡單地概括為 乙個介面,多種方法 程式在執行時才決定呼叫的函式,它是物件導向程式設計領域的核心概念。多型 polymorph...