本文的主題是構造函數不能是虛函數,首先這不需要你用腦子去記,因為當你寫出來虛構造函數時,編譯器是能檢查出來的。本文的目的是為什么構造函數不能是虛函數。
首先,先看一段錯誤的代碼,下面的代碼是通不過編譯階段的。
1 class A{ 2 public: 3 virtual A(){ 4 this->value = 0; 5 } 6 private: 7 int value; 8 };
為什么構造函數不能是虛函數呢?這里你需要知道一個概念,那就是虛函數表vtbl,每一個擁有虛成員函數的類都有一個指向虛函數表的指針。對象通過虛函數表里存儲的虛函數地址來調用虛函數。
那虛函數表指針是什么時候初始化的呢?當然是構造函數。當我們通過new來創建一個對象的時候,第一步是申請需要的內存,第二步就是調用構造函數。試想,如果構造函數是虛函數,那必然需要通過vtbl來找到虛構造函數的入口地址,顯然,我們申請的內存還沒有做任何初始化,不可能有vtbl的。因此,構造函數不能是虛函數。