1.虛函數(shù)表存放的內(nèi)容
答:虛函數(shù)表實際是一個數(shù)組醒叁,數(shù)組里存放的是虛函數(shù)的地址指針灾炭,指向虛函數(shù)夫植。
虛函數(shù)表的由來:如果一個類中有虛函數(shù)讹剔,則每一個該類的對象都會被編譯器添加一個成員:虛函數(shù)表指針油讯,這個虛函數(shù)表指針指向虛函數(shù)表,虛函數(shù)表本質(zhì)是一個數(shù)組延欠,數(shù)組中存放類中虛函數(shù)地址指針陌兑,指向虛函數(shù)。
2.虛函數(shù)表指針與虛函數(shù)表的存放位置★
答:(當前的答案不一定正確僅供參考)
①虛函數(shù)表是class specific的由捎,也就是針對一個類來說的兔综,這里有點像一個類里面的staic成員變量,即它是屬于一個類所有對象的狞玛,不是屬于某一個對象特有的软驰,是一個類所有對象共有的。
②虛函數(shù)表是編譯器來選擇實現(xiàn)的为居,編譯器的種類不同碌宴,可能實現(xiàn)方式不一樣,就像前面我們說的vptr在一個對象的最前面蒙畴,但是也有其他實現(xiàn)方式贰镣,不過目前gcc 和微軟的編譯器都是將vptr放在對象內(nèi)存布局的最前面。
③實際上虛函數(shù)指針是在構(gòu)造函數(shù)執(zhí)行時初始化的膳凝,而虛函數(shù)表是存放在可執(zhí)行文件中的碑隆。在gcc編譯器的實現(xiàn)中虛函數(shù)表vtable存放在可執(zhí)行文件的只讀數(shù)據(jù)段.rodata中
3.構(gòu)造函數(shù)可以是虛函數(shù)嗎,為什么蹬音?
答:不可以上煤,可以從兩方面解釋:第一,虛函數(shù)的作用就是在于信息不全的時候可以重載函數(shù)得到對應(yīng)的調(diào)用著淆。構(gòu)造函數(shù)本身就是要初始化實例劫狠,那使用虛函數(shù)也就沒有實際意義。所以構(gòu)造函數(shù)沒有必要是虛函數(shù)永部;第二独泞,每一個虛函數(shù)對象對應(yīng)一個虛函數(shù)指針,指向該類的一個虛函數(shù)表苔埋,虛函數(shù)指針內(nèi)存被分配在虛函數(shù)對象存儲空間的頭部懦砂,而一個類中虛函數(shù)表的創(chuàng)建是在構(gòu)造函數(shù)中被創(chuàng)建的,如果構(gòu)造函數(shù)本身就是虛函數(shù)组橄,那在執(zhí)行構(gòu)造函數(shù)的時候就需要找對應(yīng)的虛函數(shù)指針和虛函數(shù)表荞膘,而此時虛表指針和虛表還沒有被創(chuàng)建,則無法完成查找虛表而報錯玉工。
用一個不太恰當?shù)谋扔鳎豪缫粋€顯赫的家族(相當于一個類)羽资,里面可能有很多人享受著祖上的財富而吃喝玩樂,虛度光陰(虛成員函數(shù))遵班,但是在一個家族中削罩,歸根到底總要有一個刻苦努力的人來打下基業(yè)(創(chuàng)建虛函數(shù)表)瞄勾,這個能干有才的人就是構(gòu)造函數(shù)。如果假設(shè)這個打基業(yè)的人也是一個無所事事的人弥激,那豈不是打了個寂寞,后面的假設(shè)也就都不成立了愿阐。
4.析構(gòu)函數(shù)可以是虛函數(shù)嗎微服,為什么?
答:析構(gòu)函數(shù)可以是虛函數(shù)缨历,且一般基類的析構(gòu)函數(shù)均設(shè)置為虛函數(shù)以蕴,如果基類析構(gòu)函數(shù)不為虛函數(shù),那么當new-delete指向子類對象的基類指針時辛孵,執(zhí)行的操作如下:
基類構(gòu)造函數(shù)-子類構(gòu)造函數(shù)-基類的析構(gòu)函數(shù)丛肮;
從而導致子類沒有執(zhí)行子類的析構(gòu)函數(shù)而導致內(nèi)存泄露。
當基類的析構(gòu)函數(shù)被設(shè)置為虛函數(shù)時魄缚,當new-delete指向子類對象的基類指針時宝与,執(zhí)行的操作如下:
基類構(gòu)造函數(shù)-子類構(gòu)造函數(shù)-子類析構(gòu)函數(shù)-基類析構(gòu)函數(shù);
這樣就保證內(nèi)存空間不會產(chǎn)生泄露冶匹。