c 多型性 虛函式

2021-09-02 23:14:05 字數 2389 閱讀 6104

c++中多型性是指通過用virtual關鍵字來繫結同名同引數的函式,實現在編譯中進行後繫結,即在編譯過程中不繫結類,在執行時與具體的物件進行繫結,這樣就可以動態地與實際聯絡

比如乙個類 animal 有乙個虛函式breath()

魚類 fish 也有函式breath()

狗類 dog 函式breath()

具體呼叫時根據你的物件是魚類還是狗類有關

c++的多型性用一句話概括就是:在基類的函式前加上virtual關鍵字,在派生類中重寫該函式,執行時將會根據物件的實際型別來呼叫相應的函式。如果物件型別是派生類,就呼叫派生類的函式;如果物件型別是基類,就呼叫基類的函式

1:用virtual關鍵字申明的函式叫做虛函式,虛函式肯定是類的成員函式。

2:存在虛函式的類都有乙個一維的虛函式表叫做虛表,類的物件有乙個指向虛表開始的虛指標。虛表是和類對應的,虛表指標是和物件對應的。

3:多型性是乙個介面多種實現,是物件導向的核心,分為類的多型性和函式的多型性。

4:多型用虛函式來實現,結合動態繫結.

5:純虛函式是虛函式再加上 = 0;

6:抽象類是指包括至少乙個純虛函式的類。

純虛函式:virtual void fun()=0;即抽象類!必須在子類實現這個函式,即先有名稱,沒有內容,在派生類實現內容`

#include "stdafx.h"

#include #include using namespace std;

class father

void say()

};class son:public father

};void main()

我們在main()函式中首先定義了乙個son類的物件son,接著定義了乙個指向father類的指標變數pfather,然後利用該變數呼叫pfather->say().估計很多人往往將這種情況和c++的多型性搞混淆,認為son實際上是son類的物件,應該是呼叫son類的say,輸出"son say hello",然而結果卻不是.

從編譯的角度來看:

c++編譯器在編譯的時候,要確定每個物件呼叫的函式(非虛函式)的位址,這稱為早期繫結,當我們將son類的物件son的位址賦給pfather時,c++編譯器進行了型別轉換,此時c++編譯器認為變數pfather儲存的就是father物件的位址,當在main函式中執行pfather->say(),呼叫的當然就是father物件的say函式

從記憶體角度看

son類物件的記憶體模型如上圖

我們構造son類的物件時,首先要呼叫father類的建構函式去構造father類的物件,然後才呼叫son類的建構函式完成自身部分的構造,從而拼接出乙個完整的son類物件。當我們將son類物件轉換為father型別時,該物件就被認為是原物件整個記憶體模型的上半部分,也就是上圖中「father的物件所佔記憶體」,那麼當我們利用型別轉換後的物件指標去呼叫它的方法時,當然也就是呼叫它所在的記憶體中的方法,因此,輸出「father say hello」,也就順理成章了。

正如很多人那麼認為,在上面的**中,我們知道pfather實際上指向的是son類的物件,我們希望輸出的結果是son類的say方法,那麼想到達到這種結果,就要用到虛函式了。

前面輸出的結果是因為編譯器在編譯的時候,就已經確定了物件呼叫的函式的位址,要解決這個問題就要使用晚繫結,當編譯器使用晚繫結時候,就會在執行時再去確定物件的型別以及正確的呼叫函式,而要讓編譯器採用晚繫結,就要在基類中宣告函式時使用virtual關鍵字,這樣的函式我們就稱之為虛函式,一旦某個函式在基類中宣告為virtual,那麼在所有的派生類中該函式都是virtual,而不需要再顯式地宣告為virtual。

總結(基類有虛函式的):

1:每乙個類都有虛表

2:虛表可以繼承,如果子類沒有重寫虛函式,那麼子類虛表中仍然會有該函式的位址,只不過這個位址指向的是基類的虛函式實現,如果基類有3個虛函式,那麼基類的虛表中就有三項(虛函式位址),派生類也會虛表,至少有三項,如果重寫了相應的虛函式,那麼虛表中的位址就會改變,指向自身的虛函式實現,如果派生類有自己的虛函式,那麼虛表中就會新增該項。

這就是c++中的多型性,當c++編譯器在編譯的時候,發現father類的say()函式是虛函式,這個時候c++就會採用晚繫結技術,也就是編譯時並不確定具體呼叫的函式,而是在執行時,依據物件的型別來確認呼叫的是哪乙個函式,這種能力就叫做c++的多型性,我們沒有在say()函式前加virtual關鍵字時,c++編譯器就確定了哪個函式被呼叫,這叫做早期繫結。

c++的多型性就是通過晚繫結技術來實現的。

c++的多型性用一句話概括就是:在基類的函式前加上virtual關鍵字,在派生類中重寫該函式,執行時將會根據物件的實際型別來呼叫相應的函式,如果物件型別是派生類,就呼叫派生類的函式,如果物件型別是基類,就呼叫基類的函式。

c 多型性 虛函式

虛函式與純虛函式的區別 1 擁有虛函式的類可以宣告物件,但擁有純虛函式的類不可以宣告物件 只能宣告乙個指標,並且不能給其分配記憶體 並且將這個類稱為抽象類 特點 1 虛函式是動態繫結的基礎。2 是非靜態的成員函式。在類的宣告中,在函式原型之前寫virtual。不能宣告為靜態函式 3 virtual ...

多型性 虛函式

先來講講賦值相容規則。前面說過,派生類如果是從基類公有繼承的,則它會包含基類中除建構函式和析構函式外的所有成員,基類的公有成員也成為派生類的公有成員,又因為物件只能訪問類的公有成員,所以基類物件具有的功能,派生類物件都有。這樣就引出了賦值相容規則。賦值相容規則就是指在基類物件可以使用的地方都可以用公...

多型性 虛函式

虛函式是過載的另一種表現形式,是一種動態的過載方式。虛函式呼叫與函式體之間的聯絡在執行時才建立。c 中可以用基類的物件指標可以指向它的公有派生物件,當它指向公有派生類物件時,只能訪問派生類中從基類繼承來的成員,而不能訪問派生類中定義的成員。當指標指向不同的物件時,分別呼叫不同類的成員函式,如果將函式...