虚函数理解
虛函數中默認參數
/*** @file first_example.cpp* @brief 虛函數中默認參數* 規則:虛函數是動態綁定的,默認參數是靜態綁定的。默認參數的使用需要看指針或者應用本身的類型,而不是對象的類型!* @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.可以不可以?
-
靜態函數可以聲明為虛函數嗎?
原因主要有兩方面:
(1)靜態函數不可以聲明為虛函數,同時也不能被const 和 volatile關鍵字修飾
static成員函數不屬于任何類對象或類實例,所以即使給此函數加上virutal也是沒有任何意義
虛函數依靠vptr和vtable來處理。vptr是一個指針,在類的構造函數中創建生成,并且只能用this指針來訪問它,靜態成員函數沒有this指針,所以無法訪問vptr。
(2)構造函數可以為虛函數嗎?
構造函數不可以聲明為虛函數。同時除了inline|explicit之外,構造函數不允許使用其它任何關鍵字。
為什么構造函數不可以為虛函數?
盡管虛函數表vtable是在編譯階段就已經建立的,但指向虛函數表的指針vptr是在運行階段實例化對象時才產生的。 如果類含有虛函數,編譯器會在構造函數中添加代碼來創建vptr。 問題來了,如果構造函數是虛的,那么它需要vptr來訪問vtable,可這個時候vptr還沒產生。 因此,構造函數不可以為虛函數。
我們之所以使用虛函數,是因為需要在信息不全的情況下進行多態運行。而構造函數是用來初始化實例的,實例的類型必須是明確的。 因此,構造函數沒有必要被聲明為虛函數。
(3)析構函數可以為虛函數嗎?
析構函數可以聲明為虛函數。如果我們需要刪除一個指向派生類的基類指針時,應該把析構函數聲明為虛函數。 事實上,只要一個類有可能會被其它類所繼承, 就應該聲明虛析構函數(哪怕該析構函數不執行任何操作)。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
- 上一篇: 深入浅出C++虚函数的vptr与vtab
- 下一篇: C++多态的概念及前提条件(最精辟)