天天看點

構造函數能不能是虛函數????

一、構造函數不能為虛函數的理由: 

1,從存儲空間角度  

        虛函數對應一個vtable,這大家都知道,可是這個vtable其實是存儲在對象的記憶體空間的。問題出來了,如果構造函數是虛的,就需要通過 vtable來調用,可是對象還沒有執行個體化,也就是記憶體空間還沒有,怎麼找vtable呢?是以構造函數不能是虛函數。 

2,從使用角度 

        虛函數主要用于在資訊不全的情況下,能使重載的函數得到對應的調用。構造函數本身就是要初始化執行個體,那使用虛函數也沒有實際意義呀。是以構造函數沒有必要是虛函數。 

虛函數的作用在于通過父類的指針或者引用來調用它的時候能夠變成調用子類的那個成員函數。而構造函數是在建立對象時自動調用的,不可能通過父類的指針或者引用去調用,是以也就規定構造函數不能是虛函數。 

3、構造函數不需要是虛函數,也不允許是虛函數,因為建立一個對象時我們總是要明确指定對象的類型,盡管我們可能通過實驗室的基類的指針或引用去通路它 

但析構卻不一定,我們往往通過基類的指針來銷毀對象。這時候如果析構函數不是虛函數,就不能正确識别對象類型進而不能正确調用析構函數。 

4、從實作上看,vbtl在構造函數調用後才建立,因而構造函數不可能成為虛函數      從實際含義上看,在調用構造函數時還不能确定對象的真實類型(因為子類會調父類的構造函數);而且構造函數的作用是提供初始化,在對象生命期隻執行一次,不是對象的動态行為,也沒有太大的必要成為虛函數 

5、當一個構造函數被調用時,它做的首要的事情之一是初始化它的V P T R。是以,它隻能知道它是“目前”類的,而完全忽視這個對象後面是否還有繼承者。 當編譯器為這個構造函數産生代碼時,它是為這個類的構造函數産生代碼- -既不是為基類,也不是為它的派生類(因為類不知道誰繼承它)。  

    是以它使用的V P T R必須是對于這個類的V TA B L E。而且,隻要它是最後的構造函數調用,那麼在這個對象的生命期内, V P T R将 保持被初始化為指向這個V TA B L E, 但如果接着還有一個更晚派生的構造函數被調用,這個構造函數又将設定V P T R指向它的 V TA B L E,等.直到最後的構造函數結束。V P T R的狀态是由被最後調用的構造函數确定的。這就是為什麼構造函數調用是從基類到更加派生 類順序的另一個理由。  

        但是,當這一系列構造函數調用正發生時,每個構造函數都已經設定V P T R指向它自己的 V TA B L E。如果函數調用使用虛機制,它将隻産生通過它自己的V TA B L E的調用,而不是最後的V TA B L E(所有構造函數被 調用後才會有最後的V TA B L E)。

繼續閱讀