1. 程式人生 > >虛擬函式使用注意事項

虛擬函式使用注意事項

定義:

在某基類中宣告為 virtual 並在一個或多個派生類中被重新定 義的成員函式

作用:

虛擬函式主要是為了實現動態聯編,也可以說是多型。在基類當中定義了虛擬函式,可以再子類中定義和基類中相同函式名、相同引數、相同返回值和不同實現體的虛擬函式,(只要在基類中定義成為虛擬函式,子類中無需加virtual也會成為虛擬函式),實現一個介面多種形態的變成,在動態聯編當中,只能通過基類指標或基類物件來呼叫虛擬函式。 虛擬函式還有一個作用就是在開配動態記憶體是可以把基類的解構函式定義為虛的,這樣可以使得開闢的堆空間被正確的釋放,否則的話他只會呼叫基類的解構函式,不會呼叫子類的。 

不能被宣告為虛擬函式的函式:

  

普通函式(非成員函式)  因為普通函式只能被overload而不能被override,再說了把普通函式定義為虛擬函式沒有生麼實際的意義,因為函式在編譯時會被幫頂個。 

建構函式:因為建構函式主要是為了初始化物件變數的,只有在生成一個物件之後才能發揮多型的作用。而虛擬函式是在執行的時候才起作用的。 

靜態成員函式:因為靜態成員函式只拷貝一份,所有程式碼共享,沒有必要定義為虛擬函式。 

行內函數:行內函數是在編譯的時候進行程式碼替換,而虛擬函式是在執行是實現的。即使把一個函式宣告為行內函數,但編譯器在編譯的時候不一定當做行內函數。函式的inline屬性是在編譯時確定的, 然而,virtual的性質是在執行時確定的,這兩個不能同時存在,只能有一個選擇,檔案中的inline關鍵字只是對編譯器的建議,編譯器是否採納是編譯器的事情。

 

使用行內函數的時候要注意:1.遞迴函式不能定義為行內函數;2.行內函數一般適合於不存在while和switch等複雜的結構且只有1~5條語句的小函式上,否則編譯系統將該函式視為普通函式;3.行內函數只能先定義後使用,否則編譯系統也會把它認為是普通函式;4.對行內函數不能進行異常的介面宣告。
友元函式:友元函式不是類的成員函式不能被繼承。

怎麼檢測一個標記為inline的函式是否被編譯器當做行內函數來處理呢。這裡提供一個方法:使用nm來檢視呼叫行內函數的目標檔案,如果找到了inline函式的符號,那麼說明沒有被當做行內函數,如果沒有找到的話,則說明編譯器把它當做了行內函數來處理。因為如果標記為inline的函式如果被當做了行內函數,編譯器應當直接使用程式碼替換掉呼叫標記,所以不應當看到有行內函數的符號。(這個不會用)