C 多型面試題彙總

2021-10-24 07:34:57 字數 2996 閱讀 3912

總結了一些常見的面試題,通過查閱資料給出了一些淺薄的解析,歡迎各位批評指教。

inliine函式可以實虛函式碼?

不可以,因為inline函式沒有位址,無法將他存放到虛函式表中。

靜態成員可以是虛函式嗎?

不能,因為靜態成員函式中沒有this指標,使用::成員函式的嗲用用方式無法訪問虛函式表,所以靜態成員函式無法放進虛函式表。

因為:

首先什麼是static靜態成員函式?靜態成員函式不屬於類中的任何乙個物件和例項,屬於類共有的乙個函式。也就是說,它不能用this指標來訪問,因為this指標指向的是每乙個物件和例項。

對於virtual虛函式,它的呼叫恰恰使用this指標。在有虛函式的類例項中,this指標呼叫vptr指標,指向的是vtable(虛函式列表),通過虛函式列表找到需要呼叫的虛函式的位址。總體來說虛函式的呼叫關係是:this指標->vptr(4位元組)->vtable ->virtual虛函式。

所以說,static靜態函式沒有this指標,也就無法找到虛函式了。所以靜態成員函式不能是虛函式。他們的關鍵區別就是this指標。

建構函式不能為const函式,建構函式的目的就是為了給成員變數賦初值,不能為const函式

建構函式可以是虛函式嗎?

不可以,因為物件中的虛函式指標是在物件構造的時候初始化的。

因為:

虛函式對應乙個vtable,這大家都知道,可是這個vtable其實是儲存在物件的記憶體空間的。問題出來了,如果建構函式是虛的,就需要通過 vtable來呼叫,可是物件還沒有例項化,也就是記憶體空間還沒有,無法找到vtable,所以建構函式不能是虛函式。

析構函式可以是虛函式嗎?什麼場景下析構函式是虛函式?

可以,最好將析構函式設定為虛函式最好是將父類的析構函式設定為虛函式 ,因為這樣可以避免記憶體洩漏的問題。如果乙個父類的指標指向了子類的的物件,並且父類的虛函式沒有設定成虛函式,那麼子類物件中的虛函式就沒有實現多型,他只會呼叫父類的析構函式,不會呼叫子類的析構函式,但是他建立物件的時候呼叫了子類的建構函式,所以說就用子類的建構函式就應該該取呼叫他的析構函式,這樣才能保證所有的必須釋放的資源都是放了,才可以保證不會有記憶體洩漏。如果是多型的,就會先去呼叫子類的析構函式,然後再取呼叫父類的析構函式,這樣子類和父類的資源就都可以釋放。

物件訪問普通函式快還是虛函式快?

如果是普通物件,是一樣快的,如果是指標物件或者是引用物件,呼叫普通函式更快一些,因為構成了多型,執行時呼叫虛函式要先到虛函式表中去查詢。這樣然後才拿到韓式的位址,這樣就不如直接可以拿到函式位址的普通函式快。

虛函式表時再什麼階段生成的?他存放在**?

虛函式時再編譯階段生成的,他一般存放再**段,也就是常量區。

執行下面這段**的結果

#include

using

namespace std;

class

base

voidy(

)};class

derive

:public base

voidy(

)};int

main()

解析:很顯然derive繼承了base,並且實現了多型,但是只有x()是虛函式重寫,y()只在子類中宣告了虛函式,沒有在父類中聲名所以不能y()不是虛函式重寫,而是對父類中的y()重定義,所以在p呼叫y()的時候直接呼叫base中的y(),在base的y()中呼叫了x(),由於x()在子類中構成了虛函式重寫,所以呼叫子類中的x(),答案也就不曉而知了。

是否可以將類中的所有成員函式都宣告稱為虛函式,為什麼?

虛函式是在程式執行的時候通過定址操作才能確定真正要呼叫的的函式,而普通的成員函式在編譯的時候就已經確定了要呼叫的函式。這個兩者的區別,從效率上來說,虛函式的效率要低於普通成員函式,因為虛函式要先通過物件中的虛標指標拿到虛函式表的位址,然後再從虛函式表中找到對應的函式位址,最後根據函式位址去呼叫,而普通成員函式直接就可以拿到位址進行呼叫,所以沒必要將所有的成員函式宣告成虛函式。

虛函式表指標被編譯器初始化的過程怎麼理解的?

當類中宣告了虛函式是,編譯器會在類中生成乙個虛函式表vs中存放在**段,虛函式表實際上就是乙個存放虛函式指標的指標陣列,是由編譯器自動生成並維護的。虛表是屬於類的,不屬於某個具體的物件,乙個類中只需要有乙個虛表即可。同乙個類中的所有物件使用同乙個虛表,為了讓每個包含虛表的類的物件都擁有乙個虛表指標,編譯器在每個物件的頭新增了乙個指標,用來指向虛表,並且這個指標的值會自動被設定成指向類的虛表,每乙個virtaul函式的函式指標存放在虛表中,如果是單繼承,先將父類的虛表新增到子類的虛表中,然後子類再新增自己新增的虛函式指標,但是在vs編譯器中我們通常看不到新新增的虛函式指標,是編譯器故意將他們隱藏起來,如果是多繼承,在子類中新新增的虛函式指標會存放在第乙個繼承父類的虛函式表中。

多型的分類?

靜態繫結的多型的是通過函式的過載來實現的。動態繫結的多型是通過虛函式實現的。

為什麼要引入抽象類和純虛函式?

為了方便使用多型特性,在很多情況下由基類生成物件是很不合理的,純虛函式在基類中是沒有定義的,要求在子類必須加以實現,這種包含了純虛函式的基類被稱為抽象類,不能被例項化,如果子類沒有實現純虛函式,那麼它他也是乙個抽象類。

虛函式和純虛函式有什麼區別?

從基類的角度出發,如果乙個類中宣告了虛函式,這個函式是要在類中實現的,它的作用是為了能讓這個函式在他的子類中能被重寫,實現動態多型。純虛函式,只是乙個介面,乙個函式宣告,並沒有在宣告他的類中實現。對於子類來說它可以不重寫基類中的虛函式,但是他必須要將基類中的純虛函式實現。虛函式既繼承介面的同時也繼承了基類的實現,純虛函式關注的是介面的統一性,實現完全由子類來完成。

什麼是多型?他有什麼作用?

多型就是乙個介面多種實現,多型是物件導向的三大特性之一。多型分為靜態多型和動態多型。靜態多型包含函式過載和泛型程式設計,程序多型是程式呼叫函式,編譯器決定使用哪個可執行的**塊。靜態多型是由繼承機制以及虛函實現的,通過指向派生類的基類指標或者引用,訪問派生類中同名重寫成員函式。墮胎的作用就是把不同子類物件都當作父類來看,可以遮蔽不同子類之間的差異,從而寫出通用的**,做出通用的程式設計,以適應需求的不斷變化。

C 多型面試題

答 多型是物件導向的重要特性之一,它是一種行為的封裝,是同一種事物所表現出的多種形態,簡單地說是 乙個介面多種實現 有兩種型別的多型性 編譯時的多型性。編譯時的多型性是通過過載來實現的。執行時的多型性。執行時的多型性是通過虛成員實現的。1.從儲存空間角度。虛函式對應乙個vtable,這個vtable...

C 面試題彙總

c 面試題彙總 1.在什麼時候需要使用 常引用 如果既要利用引用提高程式的效率,又要保護傳遞給函式的資料不在函式中被改變,就應使用常引用。常引用宣告方式 const 型別識別符號 引用名 目標變數名 例1int a const int ra a ra 1 錯誤 a 1 正確 例2string foo...

多型面試題

題目的 如下 class a public string show a obj class b extends a public string show a obj class c extends b class d extends b a a1 new a a a2 new b b b new b...