談談關于構造函數中調用虛函數的情況,僅讨論單繼承,不考慮虛拟繼承和多重繼承。
測試平台:vs2013 + win7x64
一個例子:
輸出:
base::func
deri::func
首先讨論下對象d的構造情況。
1 先構造基類部分,調用基類base的構造函數,這個時候,派生類部分還沒有産生,這時候虛表應該是綁定基類的,自然調用的是base::func()
2 再構造派生類部分,這個時候,虛表發生變化,綁定在派生類上,調用deri::func()
雖然,在派生類中有重載func這個函數,但是,在構造基類部分的時候,派生類的成員資料還沒有初始化,如果是調用派生類中的func,會造成錯誤,記憶體越界甚至崩潰。
在函數中,可以通過列印虛表位址:
-- base::func()
int* vtl = (int*)*((int*)this);
std::cout << "base: " << this << " vtable: " << vtl << std::endl;
-- deri::func()
std::cout << "deri: " << this << " vtable: " << vtl << std::endl;
base: 0028f980 vtable: 003fdc78
deri: 0028f980 vtable: 003fdc98
發現,虛表的位址是不斷變化的。