虛函式相關討論

2021-08-07 13:33:38 字數 1821 閱讀 3495

下列關於虛函式相關說法正確的有?

(1) 多型是通過虛表實現的 (√)

(2) 建構函式可以宣告為虛函式 (x)

(3) 析構函式不可以宣告為虛函式 (x)

(4) 抽象類中至少包含乙個純虛函式 (√)

c++中 的虛函式的作用主要是實現了多型的機制。而虛函式是通過虛函式表(v-table)實現的。

建構函式為什麼不能宣告為虛函式?

1 構造乙個物件的時候,必須知道物件的實際型別。如果建構函式是虛函式,虛函式行為在執行期間才能確定實際型別。物件還未構造成功,編譯器無法知道物件的實際型別,所以建構函式不可以為虛函式。

2 虛函式的執行依賴於虛函式表。而虛函式表在建構函式中進行初始化工作,即初始化vptr,讓他指向正確的虛函式表。而在構造物件期間,虛函式表還沒有被初始化,將無法進行。

析構函式為什麼宣告為虛函式?

如果析構函式不是虛函式,而程式執行時又要通過基類的指標去銷毀派生類的動態物件,那麼用delete銷毀物件時,只呼叫了基類的析構函式,未呼叫派生類的析構函式。這樣會造成銷毀物件不完全。

順序:建構函式執行時先呼叫基類的建構函式,其次才呼叫派生類的建構函式。

析構函式執行時先呼叫派生類的析構函式,其次才呼叫基類的析構函式。

包含至少乙個純虛函式的類視為抽象類

虛函式之於析構函式的討論

1

#include

class a

~a()

};class b: public a

~b()

};int main()

結果:abab~a~a

1 宣告的是基類的指標,基類的析構函式不是虛函式,不會呼叫派生類的析構方法。

2

#include

class a

virtual ~a()

};class b: public a

~b()

};int main()

結果:abab~b~a~b~a

2 當基類的析構函式是虛函式時,基類指標指向派生類物件的空間被釋放時會自動呼叫派生類的析構函式。

3

#include

class a

~a()

};class b: public a

~b()

};int main()

結果:abab~b~a~b~a

4

#include

class a

virtual ~a()

};class b: public a

~b()

};int main()

結果:abab~b~a~b~a

由程式3、4可知,不管基類析構函式加不加virtual,只要是宣告的是派生類的指標,並且實際指向的例項是派生類的,會先呼叫派生類的析構方法,然後級聯呼叫父類的析構方法。

1 vs 2小結

在c++中,析構函式的作用是:當乙個物件被銷毀時,呼叫析構函式對類物件和物件成員進行釋放記憶體資源。

當我們定義乙個指向派生類型別物件指標時,建構函式按照從基類到派生類的順序被呼叫,但是當刪除指向派生類的基類指標時,派生類的析構函式沒有被呼叫,只是呼叫了基類的析構函式,此時派生類將會導致記憶體洩漏

我們需要將基類的析構函式宣告為虛函式,此時在呼叫析構函式的時候是根據ptr指向的具體型別來呼叫析構函式,此時會呼叫派生類的析構函式。

關於虛函式的精華討論

以下是我從網路上摘錄下來的,感覺看完這些精華討論估計對虛函式和純虛函式也理解差不多了。1.虛函式 參考書籍 com本質論 侯捷老師的 深入淺出mfc 疑問1 若是為了繼承,那麼普通的類 沒有虛函式,純虛函式 就可以被繼承,而且工作的相當好.虛函式倒是可以理解,應該是可以通過,乙個指向基類物件的指標能...

關於虛函式的精華討論

以下是我從網路上摘錄下來的,感覺看完這些精華討論估計對虛函式和純虛函式也理解差不多了。1.虛函式 參考書籍 com本質論 侯捷老師的 深入淺出mfc 疑問1 若是為了繼承,那麼普通的類 沒有虛函式,純虛函式 就可以被繼承,而且工作的相當好.虛函式倒是可以理解,應該是可以通過,乙個指向基類物件的指標能...

虛函式相關問題

1 什麼是虛函式?虛函式是在類中由virtual關鍵字宣告的成員函式,並且每乙個含有虛函式的類都會至少有乙個與之對應的虛函式表,用來存放該類所有虛函式對應的函式指標。所有虛函式位址都會存放在所屬類的虛函式表中,子類會繼承父類的虛函式表,若是子類中有與父類相同的虛函式,則會構成重寫,此時子類的虛函式指...