閱讀本文之前,讀者需要掌握 C++ 虛函數的基本用法,以及了解 C++ 的虛函數是怎麼實現的,此為基礎內容,不在本文的討論范圍。 在上次實習生面試中,面試官了我C++虛函數是怎樣實現的問題。我想讀過 Inside the C++ Object Model 這本書的人對這點都是比較熟悉的,在解釋過程中,他又問了我純虛函數是什麼,用來做什麼。我在回答的過程中簡單提了下“C++ 的純虛函數在特殊情況下是有可能會被調用的,具體的行為由 C++ 的標准庫的實現決定”,後來回想起這句話,想了好久沒想到具體的被調用的情況,幸好面試官沒追問這個問題,否則我真得語塞了(當時幾乎整個過程都是我在滔滔不絕的回答,面試官就一直嗯嗯嗯的狀態)。趁現在比較閒又不想復習考試,就順便寫寫代碼,針對這個問題總結出一篇博客文章與大家交流。 首先,必須清楚的是純虛函數本身是不應該被調用的!因為純虛函數是用來定義接口的,有時候基類自己找不到一個合情合理的實現,所以用虛函數的形式聲明,讓他的子類去做具體的實現。因此,如果純虛函數被調用了,那一定是你的程序裡出現了邏輯上的錯誤,這是我們在工作中需要了解和避免的,這也就是本文討論的目的之一啦。 你知道,虛函數是通過指針或者引用來調用的,調用的具體函數由指針/引用的實際決定。而這個實際的對象,是可以由這個對象的內存塊中的第一個值,vptr,指向虛函數表的指針來確定的。純虛函數是屬於基類的,所以要調用純虛函數,這個指針所指的對象必須是基類。但是呢,抽象類(包含了純虛函數的類)的對象是不允許被用戶定義的,唔,這個規定看似嚴謹,C++ 怎麼可能讓你去調用純虛函數,看本文的你也在好奇這個問題吧。不允許用戶定義抽象類的對象,是的,不代表這種對象不能被構造!記得對象的構造過程,是先調用基類的構造函數,再調用子類的構造函數,也就是先構造基類對象,再構造子類對象,對象的析構我就不提了哈。也就是說,在基類的構造函數裡調用的任何虛函數,都是調用基類自己的虛函數,而不是子類的虛函數,噢!漏洞就在這裡!
Base{
Pony279原創博文,轉載請注明出處 http://www.cnblogs.com/Pony279/archive/2013/06/04/3117955.html