1. 晚綁定
- 功能
為什么一個基類的指針可以知道自己指向的自己旗下的哪個派生類的實例呢?其實現(xiàn)機制就是晚綁定谎脯。
所謂的晚綁定,就是在程序運行時(而不是編譯時)決定應該執(zhí)行哪個版本的虛函數(shù) - 實現(xiàn)
編譯器為每個帶有虛函數(shù)的類都分配一個VPTR持寄,VPTR指向虛函數(shù)表(VTABLE) - 做實驗
sizeof這樣的類源梭,可以發(fā)現(xiàn)比沒有virtual函數(shù)的時候娱俺,多了4字節(jié)(一個void *的空間) - 函數(shù)尋址原理
當通過基類指針訪問某個派生類的virtual函數(shù)時,就通過這個VTABLE來尋找該執(zhí)行哪個版本的虛函數(shù)
2. 虛函數(shù)的調(diào)用規(guī)則
- 基類指針無法調(diào)用派生類中新加入的virtual或non-virtual函數(shù)(容易理解废麻,安全考慮荠卷。另外從C++語法層面來講,基類中也沒有派生類新增函數(shù)的定義)
- 如果實在需要使用基類指針來調(diào)用派生類中新加入的virtual或non-virtual函數(shù)烛愧,可以考慮向下轉(zhuǎn)型(不安全)油宜,這種情況必須事先知道Base *指向的派生類的確切類型,否則會造成難以預知的錯誤怜姿。
3.向上/向下轉(zhuǎn)型
上 ---繼承-----------繼承------------繼承---------> 下
Base Derived1 Derived2 Derived3
向上轉(zhuǎn)型就是派生類 --強制轉(zhuǎn)換--> 基類 安全
向下轉(zhuǎn)型就是基類 --強制轉(zhuǎn)換--> 派生類 不安全
4.構(gòu)造函數(shù)與虛函數(shù)
-
不要在構(gòu)造函數(shù)中調(diào)用虛函數(shù)
因為所有派生類的構(gòu)造函數(shù)結(jié)束之前验庙,虛函數(shù)機制不工作,此時只會調(diào)用本地版本 - 構(gòu)造函數(shù)也不能為虛的社牲。
解釋:由于基類到派生類的構(gòu)造函數(shù)的運行順序是:先基類在派生類粪薛,連派生類的虛函數(shù)表都還未構(gòu)建,何談多態(tài)
4. 析構(gòu)函數(shù)與虛函數(shù)
- 準則:盡量使用虛析構(gòu)函數(shù)(也可以是“總是”使用搏恤,如果你決定要在程序中使用多態(tài)性質(zhì)的話违寿。“盡量”是因為運行時多態(tài)有額外開銷熟空,你可以選擇不用它)
- 執(zhí)行順序:從最下的派生類依次往最上的基類執(zhí)行
- 使用場景:使用基類指針Base *pb釋放派生類對象時藤巢,由于整個派生鏈以及虛函數(shù)表已經(jīng)構(gòu)造好,并且析構(gòu)函數(shù)的執(zhí)行順序與構(gòu)造函數(shù)相反息罗,所以delete pb可以依次析構(gòu)從派生類到基類的所有類