關於c++虛函式,主要是服務於多型,但裡面一些細節的點還是很多的,我總結一下我目前所遇到的基本重要的幾點,通過一下幾個方面講解:
虛函式的介紹:
虛函式說白了就是成員函式前加上virtual,虛函式主要實現多型,對多型訪問子類函式方法進行操作。但是在這裡有乙個細節性的問題:虛函式是如何實現父類動態訪問子類的函式的呢?
這裡我們要知道乙個叫虛函式表的概念,當我們書寫乙個類,給類的成員函式加上virtual後,這個類的大小就會相比較沒有加virtual時,多了四個位元組。
例子:
class base
;
大家可以在vs的**源目錄檔案中,鍵入命令:/d1reportsingleclasslayout檢視想要檢視的類:
可以看到,多了乙個叫vfptr的指標,佔四個位元組,而這個指標就是指向虛函式表,所謂虛函式表,就是存放了你設計的虛函式的位址,這也就能解釋了,為什麼父類可以訪問子類的函式,就是通過虛函式指標,訪問了虛函式表中函式。
這裡要注意一點:如果子類也定義了乙個虛函式並且與父類的同名,那麼虛函式表中的函式就會把父類的虛函式位址替換成子類的。
關於虛函式表:虛函式表是在編譯階段生成的,父類有父類的vfptr指向的虛函式表,子類有子類的,當虛函式表生成後,存放在記憶體的.rodata段,也就是唯讀資料段,只可以讀取,不可以修改。
那些函式可以成為虛函式?那些函式又不能呢?
能否成為虛函式的判定方法只有兩點:
能夠產生函式符號位址;
必須依賴於物件;(只能通過物件的前四個位元組 vfptr 才能訪問虛函式表,進而訪問虛函式的位址,)
基於以上兩點,可以分析出能夠成為虛函式的有:
析構函式
普通成員函式
而不能成為虛函式的有:
建構函式:建構函式在呼叫時,還沒有產生物件;
帶靜態關鍵字static的函式:靜態成員函式是類的組成部分,不是物件的,所有物件共享乙份,沒必要設為虛函式,靜態成員函式有沒辦法繼承;
內聯函式:由於內聯函式在編譯時期被展開,變成了**塊,提高了編譯執行效率,但是虛函式的動態繫結是在執行時間完成的,所以沒法設成虛函式;
友元函式:友元函式不是類的成員函式,不支援繼承友元函式,更不能設為虛函式了
普通函式:這個就很好理解了,都不在類裡面,更別提繼承繫結什麼的了
純虛函式
知道了虛函式,理解純虛函式就不難了,虛函式中總有一些特例情況,在基類中會有一些成員方法沒法實現,只能設成純虛函式,再交給繼承類具體實現功能。
比如如下**:
class cman
;
關於虛函式的內容我大概就總結了這麼多,大致上把虛函式的內容總完了,還有就是根據虛函式的擴充套件知識,動態繫結之類的,呢些就要和靜態繫結和繼承派生結合著說了,後面再做總結。 C 虛函式表彙總
一般來說,對於開發者我們只需要知道虛函式的使用方法,以及虛函式表的存在即可。但面試時往往會遇到更細節的問題,比如讓你實現乙個虛函式機制,雖然不太實用,總歸了解些底層知識也是件好事。但如果有人苦苦相逼一定要拿這個刷人,你就去罵他吧,你才是寫編譯器的,你們全家都是寫編譯器的。唉,我有些失態了.1.虛函式...
C 虛函式表面試彙總
一般來說,對於開發者我們只需要知道虛函式的使用方法,以及虛函式表的存在即可。但面試時往往會遇到更細節的問題,比如讓你實現乙個虛函式機制,雖然不太實用,總歸了解些底層知識也是件好事。但如果有人苦苦相逼一定要拿這個刷人,你就去罵他吧,你才是寫編譯器的,你們全家都是寫編譯器的。唉,我有些失態了.1.虛函式...
C 虛函式 純虛函式
1 基本概念 虛函式是在基類中使用關鍵字virtual宣告的函式。在派生類中重新定義基類中定義的虛函式時,會告訴編譯器不要靜態鏈結到該函式。我們想要的是在程式中任意點可以根據所呼叫的物件型別來選擇呼叫的函式,這種操作被稱為動態鏈結,或後期繫結。您可能想要在基類中定義虛函式,以便在派生類中重新定義該函...