C 繼承中的多型 虛函式 虛析構函式

2022-06-21 23:15:14 字數 1686 閱讀 3825

從c++繼承中的相容原則中我們知道:父類指標可以直接指向子類物件,父類引用可以直接引用子類物件。當父類和子類有相同方法時呼叫的是父類方法,即是根據指標型別或引用型別來確定呼叫的方法型別的。如果我們想根據指標實際指向的物件型別(引用實際引用的型別)來決定呼叫的方法型別,需要把這個函式宣告為虛函式,這就是多型。

#include using

namespace

std;

class

a

virtual

void

printv()

};class b:public

a

virtual

void

printv()

};void test(a *pa)

intmain()

view code

執行結果:

i am a

i am vb

多型成立的條件 :

1 要有繼承

2 要有虛函式重寫

3 要有父類指標(父類引用)指向子類物件

建構函式不能是虛函式。建立乙個派生類物件時,必須從類層次的根開

始,沿著繼承路徑逐個呼叫基類的建構函式。

析構函式可以是虛的。虛析構函式用於指引delete 運算子正確析構動態物件。

#include using

namespace

std;

class

a

virtual ~a()

private

:

char *p;

};class b:public

a ~b()

private

:

char *p;

};class c:public

b ~c()

private

:

char *p;

};void test(a *pa)

intmain()

view code

執行結果:

a()

b()c()

~c()

~b()

~a()

view code

當類中宣告虛函式時,編譯器會在類中生成乙個虛函式表;

虛函式表是乙個儲存類成員函式指標的資料結構;

虛函式表是由編譯器自動生成與維護的;

virtual成員函式會被編譯器放入虛函式表中;

存在虛函式時,每個物件中都有乙個指向虛函式表的指標(vptr指標)。

當呼叫函式func時,編譯器首先確定func是不是虛函式:

(1)func不是虛函式:編譯器可以直接確定被呼叫的函式(靜態鏈編,根據指標或引用型別確定)

(2)func是虛函式:編譯器根據實際指向的物件的vptr指標指向的虛函式表查詢func函式並呼叫(動態鏈編,執行時完成)

說明:1. 通過虛函式表指標vptr呼叫重寫函式是在程式執行時進行的,因此需

要通過定址操作才能確定真正應該呼叫的函式。 而普通成員函式是在編譯時就

確定了呼叫的函式。在效率上,

虛函式的效率要低很多。

2.出於效率考慮,沒有必要將所有成員函式都宣告為虛函式.

繼承(多型和虛析構函式)

派生類不能直接訪問基類的私有成員,必須通過基類方法進行訪問。建立派生類物件時,首先建立基類物件。也就是說基類物件在程式進入派生類建構函式之前被建立。c 使用成員初始化列表來完成。派生類建構函式初始化基類私有成員,採用成員初始化列表。總結 首先,若基類函式需要被派生類重定義,則需要將其在基類宣告為虛函...

C 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...

C 虛析構函式 純虛析構函式

虛析構函式 析構函式的工作方式是 最底層的派生類 most derived class 的析構函式最先被呼叫,然後呼叫每乙個基類的析構函式。因為在c 中,當乙個派生類物件通過使用乙個基類指標刪除,而這個基類有乙個非虛的析構函式,則結果是未定義的。執行時比較有代表性的後果是物件的派生部分不會被銷毀。然...