虚函数理解
虛函數(shù)中默認(rèn)參數(shù)
/*** @file first_example.cpp* @brief 虛函數(shù)中默認(rèn)參數(shù)* 規(guī)則:虛函數(shù)是動態(tài)綁定的,默認(rèn)參數(shù)是靜態(tài)綁定的。默認(rèn)參數(shù)的使用需要看指針或者應(yīng)用本身的類型,而不是對象的類型!* @author 光城* @version v1* @date 2019-07-24*/#include <iostream> using namespace std;class Base { public:virtual void fun ( int x = 10 ){cout << "Base::fun(), x = " << x << endl;} };class Derived : public Base { public:virtual void fun ( int x=20 ){cout << "Derived::fun(), x = " << x << endl;} };int main() {Derived d1;Base *bp = &d1;bp->fun(); // 10return 0; } Derived::fun(), x = 104.可以不可以?
-
靜態(tài)函數(shù)可以聲明為虛函數(shù)嗎?
原因主要有兩方面:
(1)靜態(tài)函數(shù)不可以聲明為虛函數(shù),同時也不能被const 和 volatile關(guān)鍵字修飾
static成員函數(shù)不屬于任何類對象或類實(shí)例,所以即使給此函數(shù)加上virutal也是沒有任何意義
虛函數(shù)依靠vptr和vtable來處理。vptr是一個指針,在類的構(gòu)造函數(shù)中創(chuàng)建生成,并且只能用this指針來訪問它,靜態(tài)成員函數(shù)沒有this指針,所以無法訪問vptr。
(2)構(gòu)造函數(shù)可以為虛函數(shù)嗎?
構(gòu)造函數(shù)不可以聲明為虛函數(shù)。同時除了inline|explicit之外,構(gòu)造函數(shù)不允許使用其它任何關(guān)鍵字。
為什么構(gòu)造函數(shù)不可以為虛函數(shù)?
盡管虛函數(shù)表vtable是在編譯階段就已經(jīng)建立的,但指向虛函數(shù)表的指針vptr是在運(yùn)行階段實(shí)例化對象時才產(chǎn)生的。 如果類含有虛函數(shù),編譯器會在構(gòu)造函數(shù)中添加代碼來創(chuàng)建vptr。 問題來了,如果構(gòu)造函數(shù)是虛的,那么它需要vptr來訪問vtable,可這個時候vptr還沒產(chǎn)生。 因此,構(gòu)造函數(shù)不可以為虛函數(shù)。
我們之所以使用虛函數(shù),是因?yàn)樾枰谛畔⒉蝗那闆r下進(jìn)行多態(tài)運(yùn)行。而構(gòu)造函數(shù)是用來初始化實(shí)例的,實(shí)例的類型必須是明確的。 因此,構(gòu)造函數(shù)沒有必要被聲明為虛函數(shù)。
(3)析構(gòu)函數(shù)可以為虛函數(shù)嗎?
析構(gòu)函數(shù)可以聲明為虛函數(shù)。如果我們需要刪除一個指向派生類的基類指針時,應(yīng)該把析構(gòu)函數(shù)聲明為虛函數(shù)。 事實(shí)上,只要一個類有可能會被其它類所繼承, 就應(yīng)該聲明虛析構(gòu)函數(shù)(哪怕該析構(gòu)函數(shù)不執(zhí)行任何操作)。
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
- 上一篇: 深入浅出C++虚函数的vptr与vtab
- 下一篇: 超过1000本的计算机经典书籍分享