來源:http://blog.sina.com.cn/s/blog_620882f401016ri2.html
1,從存儲空間角度
虛函數對應一個vtable,這大家都知道,可是這個vtable的指針其實是存儲在對象的內存空間的。問題出來了,如果構造函數是虛的,就需要通過 vtable來調用,可是對象還沒有實例化,也就是內存空間還沒有,無法找到vtable,所以構造函數不能是虛函數。
2,從使用角度
虛函數主要用於在信息不全的情況下,能使重寫的函數得到對應的調用。構造函數本身就是要初始化實例,那使用虛函數也沒有實際意義呀。所以構造函數沒有必要是虛函數。
虛函數的作用在於通過父類的指針或者引用來調用它的時候能夠變成調用子類的那個成員函數。而構造函數是在創建對象時自動調用的,不可能通過父類的指針或者引用去調用,因此也就規定構造函數不能是虛函數。
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)(批注:保留疑問,等后來再看可能就明白了)。