C 多型理解

2021-08-21 14:25:34 字數 1708 閱讀 1518

多型

什麼是多型????

其實也可以說是一種介面,多種實現方法。

分為靜態多型和動態多型。

靜態多型分為函式過載和泛型程式設計,也可以說是靜態聯編,在編譯期間就可以確定了。

函式過載主要是函式的引數列表的不同(資料型別的不同和引數個數的不同)

泛型程式設計就是建立乙個模板,輸入不同的資料型別也可以實現想要的功能。

動態多型,也可以說是動態聯編,根據虛函式呼叫不同的函式,根據函式呼叫的動態繫結。

這是因為每個有虛函式的類或者虛繼承的子類,編譯器都會為它生成乙個虛函式表(簡稱:虛表),表中的每乙個元素都指向乙個虛函式的位址。(注意:虛表是從屬於類的) 

1、建構函式能不能作為虛函式呢?

建構函式的作用我們都知道,是建立物件的,而虛函式的呼叫是通過物件來進行的,這是矛盾的,所以說建構函式不能宣告成虛函式。

2、靜態成員函式可以宣告成虛函式嗎?

如果定義成靜態成員函式,那麼在這個函式可以通過類名和域作用符來呼叫,也就是說,不用建立物件就可以呼叫。

虛表位址的使用必須通過物件的位址才能獲取。

重點是:!!!!虛表是通過物件實現的,繞開它或者衝突都會報錯

3、析構函式最好宣告成虛函式,為什麼?

析構函式宣告成虛函式的時候,會有效的避免記憶體洩漏(忘了delete 子類的析構函式)。

注意:!!!

不要在建構函式和析構函式中呼叫虛函式!因為在建構函式和析構函式中物件是不完整的,呼叫虛函式可能會出現未定義的問題!

純虛函式

您可能想要在基類中定義虛函式,以便在派生類中重新定義該函式更好地適用於物件,但是您在基類中又不能對虛函式給出有意義的實現,這個時候就會用到純虛函式。

虛表!!!

編譯器對每個包含虛函式的類建立乙個虛函式表vtable,表中每一項指向乙個虛函式的位址,即vtable表可以看成乙個函式指標的陣列,每個虛函式的入口位址就是這個陣列的乙個元素。

每個含有虛函式的類都有各自的一張虛函式表vtable。每個派生類的vtable繼承了它各個基類的vtable,如果基類vtable中包含某一項(虛函式的入口位址),則其派生類的vtable中也將包含同樣的一項,但是兩項的值可能不同。如果派生類中過載了該項對應的虛函式,則派生類vtable的該項指向過載後的虛函式,如果派生類中沒有對該項對應的虛函式進行重新定義,則使用基類的這個虛函式位址。

在建立含有虛函式的類的物件的時候,編譯器會在每個物件的記憶體布局中增加乙個vptr指標項,該指標指向本類的vtable。在通過指向基類物件的指標(設為bp)呼叫乙個虛函式時,編譯器生成的**是先獲取所指物件的vtb1指標,然後呼叫vtb1所指向類的vtable中的對應項(具體虛函式的入口位址)。

當基類中沒有定義虛函式時,其長度=資料成員長度;派生類長度=自身資料成員長度+基類繼承的資料成員長度;

當基類中定義虛函式後,其長度=資料成員長度+虛函式表的位址長度;派生類長度=自身資料成員長度+基類繼承的資料成員長度+虛函式表的位址長度。

包含乙個虛函式和幾個虛函式的類的長度增量為0。含有虛函式的類只是增加了乙個指標用於儲存虛函式表的首位址。

派生類與基類同名的虛函式在vtable中有相同的索引號(或序號)

C 多型理解

封裝 繼承 多型,物件導向的三大特性,前兩項理解相對容易,但要理解多型,特別是深入的了解,對於初學者而言可能就會有一定困難了。我一直認為學習oo的最好方法就是結合實踐,封裝 繼承在實際工作中的應用隨處可見,但多型呢?也許未必,可能不經意間用到也不會把它跟 多型 這個詞對應起來。在此拋磚引玉,大家討論...

C 多型的理解

一 什麼是多型 物件導向程式設計中的另外乙個重要概念是多型性。在執行時,可以通過指向基類的指標,來呼叫實現派生類中的方法。可以把一組物件放到乙個陣列中,然後呼叫它們的方法,在這種場合下,多型性作用就體現出來了,這些物件不必是相同型別的物件。當然,如果它們都繼承自某個類,你可以把這些派生類,都放到乙個...

C 中多型理解

封裝 繼承 多型,物件導向的三大特性,前兩項理解相對容易,但要理解多型,特別是深入的了解,對於初學者而言可能就會有一定困難了。我一直認為學習oo的最好方法就是結合實踐,封裝 繼承在實際工作中的應用隨處可見,但多型呢?也許未必,可能不經意間用到也不會把它跟 多型 這個詞對應起來。在此拋磚引玉,大家討論...