虛函式 和 純虛函式

2021-06-07 14:56:17 字數 1448 閱讀 4180

簡單的說,「介面」就是該類的public函式。由於在類的外部一般只能通過這些公共函式才能訪問乙個類,所以這些函式就稱為類的介面。雖然乙個類也可以存在public成員資料,但是,一般不要編寫這種能夠直接在類的外部訪問的public資料,因為這樣就使資訊隱藏性受到一定的「破壞」。

當使用乙個基類的指標指向其乙個派生類的實體時,利用該指標呼叫乙個函式,如果這個函式在基類的定義中使用了virtual關鍵字,那麼,這個函式在派生類中自動也是虛函式(前提:此函式沒有被「過載」[注:過載的實質是函式名未發生改變,但是函式的引數個數、引數型別、或者型別的順序發生改變,過載也叫做「靜態多型性」],但是可以重新定義其可執行語句)。這個時候,就會發生函式的動態繫結--也就是執行的函式不再是指標所屬類的成員函式,而是針所指向的物件對應類的同名函式。

例如,以下的**片段:

class   base

//基類裡面的虛函式

......

}; class   derived   :public   base

//該函式在派生類自動為虛函式

......

}; int   main()

那麼,這是不是說,如果有以下的語句:

base   *pb;

pb=new   base;

pb-> get();

函式就不再是動態繫結呢?答案是:還是動態繫結。只要用 "pointer-> virtual_function(); ",就會發生函式呼叫的動態繫結。

這是為什麼呢?

這是因為,編譯器再編譯上述**的時候,做了三項工作:

1、為每乙個含有虛函式的類製造乙個唯一的虛函式表(vtable),虛函式表是乙個虛函式入口位址陣列,每乙個成員就是乙個虛函式的指標(入口位址);

2、每例項化乙個含有虛函式的物件,就為該物件增加乙個vptr(虛函式表指標)做為該物件的首成員資料,它儲存的值固定的,即其所屬類的vtable位址;

3.1   訪問pointer所指向的真實物件的vptr,從而得到該物件所屬類的唯一vtable位址;

3.2   訪問vtable,查閱被調函式的位址;

3.3   按照3.2的結果,執行相應的函式**.

純虛函式是在基類裡面,沒有給出實現,而是直接賦值為0的虛函式.例如:

class   instrument

純虛函式沒有任何動作,也沒有入口位址,因而不會填寫vtable裡面的指標的值,僅僅用作佔據虛函式表位置(因為無論你在派生類裡用什麼樣的順序實現多個虛函式,在派生類的虛函式表中,從基類繼承來的虛函式在派生類的vtable中的順序,仍然保持與基類的相同).

此外,純虛函式還有兩個作用:

一是,純虛函式表示其所屬類是乙個抽象類(至少包含乙個純虛函式的類叫作抽象類),抽象類不能被例項化;

二是,純虛函式表示其自身僅僅是乙個基類介面,其所屬類的某個派生類必須實現這個介面函式.否則,派生類還是包含純虛函式,還是抽象類,不能被例項化;

虛函式和純虛函式

除了繼承外,c 的另乙個優良特性是支援多型,即允許將派生類的物件當作基類的物件使用。如果a是基類,b和c是a的派生類,多態函式test的引數是a的指標。那麼test函式可以引用a b c的物件。示例程式如下 class a void test a a class b public a class c...

純虛函式和虛函式

首先 強調乙個概念 定義乙個函式為虛函式,不代表函式為不被實現的函式。定義他為虛函式是為了允許用基類的指標來呼叫子類的這個函式。定義乙個函式為純虛函式,才代表函式沒有被實現。定義純虛函式是為了實現乙個介面,起到乙個規範的作用,規範繼承這個類的程式設計師必須實現這個函式。1 簡介 假設我們有下面的類層...

虛函式和純虛函式

一 定義 都有virtual關鍵字 乙個函式為虛函式,該函式可以實現,允許用基類的指標呼叫子類的同名函式。乙個函式為純虛函式,該函式不能實現,子類繼承這個類必須實現這個函式才能例項化物件。class a class b void main 二 用法 有純虛函式的類是抽象類,不能生成物件,只能派生。他...