在函式定義之前加上關鍵字virtual的函式被稱為虛函式。
虛函式是實現多型性的手段之一,也就是雖然它有一樣的宣告,但是具體下到不同的類當中,實現的方法又有所差別
下面通過乙個例項來理解虛函式
#include
using
namespace std;
class
base};
class
derived1
:public base };
class
derived2
:public base };
intmain()
程式裡面還定義了基類指標,展示了這種用法,通過指標來呼叫函式。p所指的物件的型別決定了執行vfunc的哪乙個形式。此外,在執行時也可以得出這個結論,形成了執行時多型性的基礎。當然使用一般的類運算子"."也是可以進行呼叫的
c++為了支援多型性,引入了動態繫結和靜態繫結。
靜態繫結是指繫結的是物件的靜態型別,某乙個特性(比如函式)依賴於物件的靜態型別,發生在編譯時期;動態繫結指的是繫結了物件的動態型別,特性依賴於物件的動態型別會發生在執行期。
只有才用「指標->函式」或「引用物件.函式」的方法呼叫c++類中的虛函式才會執行動態繫結。
#include
using
namespace std;
class
cbase};
class
cderived
:public cbase};
void
main()
執行結果:
cderived function
cderived function
cderived function
cbase function
當引用或者指標在執行過程中被建立呼叫物件的過程,由於是在編譯執行的時候進行的,所以是一種動態繫結,因此,一般情況下也只有通過位址,即指標和引用才能進行動態繫結
有一類虛函式,在基類當中並不能給出很好的實現,還不如放到子類當中進行功能實現的,可以使用純虛函式,帶有純虛函式的類稱為抽象類。
純虛函式的定義格式為
virtual 函式型別 函式名(引數) = 0;
純虛函式只需要宣告,如果寫了具體的定義也會被編譯器忽略
抽象類是一種沒有具體實現方法的類,只是作為乙個基類來實現對事物的抽象,乙個抽象類也是不能定義物件的,只能作為基類被繼承,由它作為乙個公共的介面,實現多型性。
當乙個類繼承了基類的時候,派生類就實現了基類中定義的虛函式。如果乙個派生類沒有將基類的純虛函式全部實現,那麼這個派生類仍然是乙個抽象類,不能用來定義物件。如果乙個派生類將抽象類全部實現了,那麼這個派生類就不是乙個抽象類了
虛函式不能作為建構函式,因為如果作為的話初始化物件時就不能確定正確的成員資料型別,但是析構函式可以宣告為虛函式
#include
#include
using
namespace std;
classa}
;classb:
public a
virtual~b
()private
:char
* buf;};
void
fun(a* a)
void
main()
b::~b()
a::~a()
本例中,定義了乙個類a,在基類中定義了乙個虛析構函式。接下來,定義了該類的乙個子類,定義了虛析構函式呼叫a的析構函式,同時定義了乙個fun函式來對a的申請的控制項進行刪除。在主函式中定義了乙個a的指標,用子類b的物件來初始化,然後呼叫fun函式,執行結果證明先呼叫了b的析構函式然後呼叫a的析構函式,也就是說在呼叫b的析構函式之後,系統執行時發現析構函式繼承自a,就再呼叫一次a中的虛析構函式
實際生活中,乙個事物往往擁有多個屬性,在物件導向程式設計方法中,引入了多重繼承的概念,即乙個派生類可以有多個基類。
比如交通工具類可以派生出車和船兩個子類,但是水陸兩用船就必須繼承車和船的屬性
抽象類的多重繼承與類的多重繼承使用方法是一樣的
c++中式通過虛函式表實現虛函式的呼叫。虛函式表(v-table)主要儲存的就是某個類的虛函式的位址,還儲存了這個虛函式由哪個類繼承實現,這個表能夠真實地反映函式的繼承情況。
其實,虛函式表只起到了地圖的作用,當有乙個派生類通過父類的指標來進行操作時,就可以查詢虛函式表中的位址以尋找虛函式所佔到的記憶體位址了。
使用虛函式表的過程是這樣的:通過乙個物件位址以尋找該錶的位址,遍歷該表中儲存的虛函式的位址,通過位址呼叫相應的函式
1.為了提高程式的清晰性,最好在類的每乙個層次中都顯式宣告這些函式
2.沒有定義虛函式的派生類簡單的繼承了其直接基類的虛函式
3.如果乙個函式被定義為虛函式,那麼重新定義類時即便沒有宣告這個虛函式,在之後的繼承類層結構中都是虛函式
如果乙個類中含有純虛函式,那麼任何試圖對這個類進行例項化的操作都是錯誤的,因為抽象基類是不能直接被呼叫的,只能由子類進行繼承並呼叫子類的方法
虛函式和純虛函式的定義中不能有static識別符號,因為被static修飾的函式在編譯的時候要求前期繫結,然而虛函式是動態繫結的
c 學習記錄17 虛函式和純虛函式
本文 定義乙個函式為虛函式,不代表函式為不被實現的函式。定義他為虛函式是為了允許用基類的指標來呼叫子類的這個函式。定義乙個函式為純虛函式,才代表函式沒有被實現。定義純虛函式是為了實現乙個介面,起到乙個規範的作用,規範繼承這個類的程式設計師必須實現這個函式。假設我們有下面的類層次 class a 這個...
C 語言學習記錄 10 內聯函式
內聯函式指的是一種在呼叫函式時提高執行效率的一種機制。在編譯器編譯的時候,用函式體裡面的語句去替換函式呼叫表示式,不需要引數呼叫及返回,以省去呼叫時和轉子函式並返回時所用的資源和開銷。內聯函式實際上是通過乙個inline關鍵字將函式從函式體中引入主函式,就直接存放在主函式中,從而減少呼叫函式所需要的...
C 多型 虛函式 純虛函式和抽象函式
多型 虛函式 純虛函式和抽象函式 多型按字面的意思就是多種形態。當類之間存在層次結構,並且類之間是通過繼承關聯時,就會用到多型。c 多型意味著呼叫成員函式時,會根據呼叫函式的物件的型別來執行不同的函式。其主要是函式的多種形態 乙個函式實現多種功能,形式是乙個乙個覆蓋。例項如下 includeusin...