C 語言學習記錄 27 虛函式和抽象類

2021-10-14 07:46:08 字數 2639 閱讀 6300

在函式定義之前加上關鍵字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...