C 繼承與多型之虛函式

2021-10-04 20:59:05 字數 2366 閱讀 8176

一、定義

虛函式必須是基類的非靜態成員函式,其訪問許可權可以是private或protected或public,在基類的類定義中定義虛函式的一般形式。

虛函式是一種在基類定義為virtual的函式,並在乙個或多個派生類中再定義的函式。實現多型性。虛函式的特點是,只要定義乙個基類的指標,就可以指向派生類的物件。

二、具體實現

我們先看一段簡單的**:

#include

using

namespace std;

class

base

~base()

void

show()

protected

:int ma;};

class

derive

:public base

~derive()

void

show()

private

:int mb;};

intmain()

這個**的執行結果是:

現在我們在基類函式中加入virtual關鍵字:

virtual

void

show()

加上關鍵字後我們發現執行的結果發生是這樣的:

和我們之前完全不一樣:首先基類中多出了四個位元組,派生類中也多出了四個位元組。然後解引用的時候發現列印的是派生類。而且呼叫的是派生類下的show函式。但為什麼一加virtual關鍵字後會發生這麼大的變化呢?

我們先看一下基類的記憶體布局:

我們發現加上虛函式之後會出現乙個虛函式指標並且指向了乙個虛函式表

1、首先我們先分析他為什麼多出了四個位元組

我們發現多了四個位元組,也就是多了乙個指標。既然基類中有虛函式,如果它有虛函式證明它就要有虛函式表,那麼在這個物件的記憶體裡面也就應該有虛函式指標來指向這個虛函式表,所以有了函式指標他也就多了四個位元組。那麼為什麼派生類中也多出了四個位元組呢?

我們首先要知道乙個規定:基類中是虛函式派生類中同名函式也是虛函式。那如果基類中的show函式是虛函式,那麼派生類中和它同名的函式show函式也就會是虛函式函式,這樣派生類中就會多出四個位元組。

2、我們現在分析為什麼解引用之後列印的卻是class derive

這個時候我們就需要知道它的虛函式表裡存放的是什麼

首先存放的是rtti資訊(runtime type infomation)

然後是偏移量(vfptr相對於整個記憶體布局的偏移),因為vfptr的優先順序是最高的,所以它的偏移量一般是0

接下來第三個模組放的是虛函式的位址。

那為什麼列印的是class derive呢?

因為基類的虛函式表中的rtti存放的是class base。派生類的虛函式表中的rtti存放的是class derive。我們用了乙個基類的指標指向了乙個派生類的物件。

base* pb =

newderive(10

);

然後pb進行了解引用,那麼它的本質也就成了派生類的物件,我們現在提取rtti資訊時就提取成了派生類的虛函式表的資訊了,就成了class derive

3、現在分析為什麼呼叫的是derive::show

這是乙個派生類的記憶體布局以及派生類對應的虛表。現在是用了乙個基類的指標(佔四個位元組),那裡面存放的就是派生類物件的位址,也就是pb指向了派生類物件。因為是乙個基類指標,所以只能用基類的部分(圖中紅色的部分)。但這個基類中的vfptr指向的vftable是派生類的vftable。

現在如果再通過pb呼叫show的話。需要先通過pb所指向的位址的vfptr找到show函式的入口位址來呼叫,這個show函式是派生類的show函式。也就是為什麼最後列印出來的derive::show(圖中藍色部分)

C 繼承 多型 虛函式

c 支援多繼承 class parent class parent2 class child public parent,private parent2公有繼承和私有繼承的區別 public parent 公有繼承,private和public都會繼承 private parent 私有繼承,只繼承...

c 筆記之繼承,多型,虛函式雜談

1.基類中成員的繼承 在某本書上看到 子類擁有父類所有非private的屬性和功能 當時就在想,那private的成員和方法呢?能被繼承嗎?上網搜了好久,各種說法都有,有的說不能繼承 有的說能繼承,但是不能訪問 有的說不能訪問,所以不能算繼承 後來自己寫了幾段 來驗證了一下。首先宣告,我並不知道繼承...

C 繼承 多型 虛函式 抽象

一 繼承 1 如果你以乙個 基類指標 指向 派生類物件 那麼經由該指標你只能呼叫基類所定義的函式 2 如果你以乙個 派生類指標 指向乙個 基類指標 你必須先做明顯的轉型操作。3 如果基類和派生類都定義了相同名稱的成員函式,那麼通過物件指標呼叫成員函式是,到底呼叫到那乙個函式,必須視該指標的原始型別而...