C 虛函式五問

2021-08-01 15:33:26 字數 1703 閱讀 2705

前言

c++虛函式主要是為了過載和多型的需要,其中虛函式在基類中是有定義的,因此,虛函式可以選擇在子類中重新定義,也可以選擇不管,但是純虛函式則必須要在子類中重新定義,否則子類繼承了基類之後依舊是帶有純虛函式的,無法例項化物件。

示例

#include

"stdafx.h"

#include

class parent

;void

parent

::move()

void

parent

::output()

class son:public

parent

;void son::stand()

void son::output()

int main()

如上**所示,首先建立兩個類parent和son,其中parent類中定義兩個成員函式,乙個是虛函式output(),乙個是普通函式move();而son類則是parent類的子類,同樣定義兩個成員函式,這裡需要注意,parent()類中output()是虛函式,前面說了,在子類中可以選擇重新定義,也可以選擇不用,一會一點一點驗證;

接下來在main()函式中定義乙個子類的物件s,和乙個parent類的物件指標,並將子類物件的指標賦值給父類的指標;

問:子類的物件指標賦值給了父類的指標p,那麼p能否呼叫stand()?

答:當然不能,這個是新人把概念混淆之後出現的錯覺導致的,因為他們會覺得,將s賦值給了p,是不是s的所有東西都給了p,其實p依舊只是parent類的指標而已,因此p指標所指物件的成員函式只能是output()和move();

問:p.output()輸出的結果應該是什麼?

答:是son,原因是因為p的指標被賦值了s的物件,因此是son;

再問:如果將son::output()函式去掉會如何?因為前面說了,子類可以也可以不重新定義虛函式!

答:是parent,因為如果子類沒有重寫虛函式,便是繼承的父類函式,因此是parent;

問:子類中的output()能不能為普通函式,即,去掉virtual?

答:可以,去掉之後,子類再次被派生時,就需要按照普通函式對待。

class parent

parent a;

定義乙個類parent,並將其實例化物件a,則a的內部儲存關係如下所示:

此時,如果對該類繼承,則在其子類中,虛表向後延續,如果子類對虛函式重寫,則用子類去覆蓋基類虛函式位置,因為,虛函式表的指標必須存在於物件例項中最前面的位置;

問:如果在son s定義之後,對s賦值為0會如何?

例如:

son s;

::memset(&s,0,sizeof(s));

parent

&p=s;

p.output();

答:沒有結果,程式出錯,其原因就是上面的理由,呼叫memset()之後會把虛表指標修改為0,從而無法通過該虛表指標找到虛表,因此會導致程式執行出錯!

C 面試100問 虛函式

參考 實現了多型機制。多型 polymorphism 允許將子類型別的指標賦值給父類型別的指標,賦值之後,父指標就可以根據當前賦值給它的子型別的特性以不同的方式運作。charlie calverts對多型的描述 多型性是允許你將父物件設定成為乙個或更多的他的子物件相等的技術,賦值之後,父物件就可以根...

C 語法細微 五 多型虛函式

多型 polymorphism 多型性是指覺有不同功能的函式可以用乙個函式名 這樣就可以用乙個函式名呼叫不同內容的函式 想不同德物件傳送同一訊息 不同的物件接收到時會產生不同的行為 靜態多型性和動態多型性 靜態多型性是在程式編譯時就能決定的 函式過載 運算子過載 動態多型性是在程式執行過程中決定的 ...

C 虛函式 純虛函式

1 基本概念 虛函式是在基類中使用關鍵字virtual宣告的函式。在派生類中重新定義基類中定義的虛函式時,會告訴編譯器不要靜態鏈結到該函式。我們想要的是在程式中任意點可以根據所呼叫的物件型別來選擇呼叫的函式,這種操作被稱為動態鏈結,或後期繫結。您可能想要在基類中定義虛函式,以便在派生類中重新定義該函...