C 多型解析

2021-12-30 05:18:45 字數 3434 閱讀 2274

因為,我們編寫**時,有的時候,當物件不同時,就需要呼叫不同的函式。在這個時候就需要使用的多型了。

再說類的多型性之前我先來說說物件這個概念。

物件的概念可以分為兩種型別

所謂的靜態型別,就是一般的型別 。。。

而動態型別,舉個例子來說就像是賦值相容規則裡說的

乙個基類物件可以用 派生類物件來賦值;在這裡的這個物件就是動態型別的。

因為只有在執行時呼叫物件時 才知道呼叫的實際上是乙個派生類的物件。。。

多型概念:多型這一特性,用通俗的話來說就是 乙個事物在不同的時候表現為多種狀態。。。。

但是在c++中多型有這更為廣泛的含義

所謂靜態多型,指的是編譯器在編譯期間完成的,編譯器根據函式實參的型別(可能會進行隱式型別轉換),可推

斷出要呼叫那個函式,如果有對應的函式就呼叫該函式,否則出現編譯錯誤。

函式過載,編譯器在編譯時,就已經判斷出引數的型別 ,根據型別的不同來呼叫不同的函式。

模板 ,也如函式過載一般,根據模板引數的不同呼叫函式。

函式過載例子:

關於模板的示例可以看看我之前寫的c++函式模板

動態繫結指的是在程式執行期間(非編譯期)判斷所引用物件的實際型別,根據其實際型別呼叫相應的方法。

在這裡我們動態多型講的主要是 說 虛函式

虛函式使用virtual關鍵字修飾類的成員函式時,指明該函式為虛函式,派生類需要重新實現,編譯器將實

現動態繫結。

下面來舉個虛函式的示例:

class b

};class d:public b

};int main()

**執行結果:

從輸出的結果上我們看出

b.base();//呼叫的是基類的函式

b1->base();//呼叫的是派生類的函式

d.base();//呼叫的是派生類的函式

函式呼叫時b1呼叫的是物件d記憶體,所以呼叫的是派生類的函式;;;;

【動態繫結條件】

1、必須是虛函式

2、通過基類型別的引用或者指標呼叫虛函式

下面說說在多型中 我們可能會遇到幾種函式名相同的情況:

1、函式過載

限定條件為:

1)在同一作用域內;(一定要記住這一點)

2)函式名相同;

3)引數列表相同(引數的順序 ,型別 ,長度)

2、同名隱藏

限定條件為:

1)乙個在基類中,乙個在派生類裡;

2)函式名相同;

3、函式重寫

限定條件為:

1)乙個在基類中,乙個在派生類裡

2)都是虛函式;

3)函式原型相同(函式名,引數,返回值相同)

4、協變

限定條件為:

1)乙個在基類中,乙個在派生類裡

2)都是虛函式

3)函式名相同,引數列表相同

4)函式返回值分別為基類的指標(引用),派生類類的指標(引用)

下面有一段**我們來看看

class b

void test2(int _test)

void test3(int _test)

virtual b* test4(int _test1, int _test2)

};

class d :public b

virtual void test2(int _test)

void test3(int _test)

virtual d* test4(int _test1, int _test2)

};上述**中

test1()屬於函式重寫

test2()屬於虛函式

test3()屬於同名隱藏

test4()屬於協變

所謂純虛函式

在成員函式的形參後面寫上=0,則成員函式為純虛函式。

包含純虛函式的類叫做抽象類(也叫介面類),抽象類不能例項化出物件。純虛函式在派生類中重新定義以後,派生類才能例項化出物件。

用**來直觀說明一下吧

class base

;class derived :public base

{};在這段**中,base就是乙個抽象類,而test函式就是乙個純虛函式

所以,不能使用base類 來定義乙個物件 。

那些函式可以定義為虛函式呢?????

總結一句話就是 只有類的非靜態成員函式才能定義為虛函式

但是類的建構函式不能定義為虛函式,因為建構函式是在類物件建立時呼叫的,

而虛函式是通過基類的指標和派生類的指標和引用呼叫的,

如果將建構函式定義為虛函式,無法正常實現虛函式與建構函式的功能。

一般情況下,要將基類析構函式定義為虛函式,為什麼呢???

class base

;class derived :public base

;當宣告乙個基類的引用 ,用派生類賦值int mian()

當函式結束後 ,rb類析構時,應該呼叫的派生類的析構函式,所以應該將基類的析構函式定義為虛函式,

來根據引數的不同呼叫不同的析構函式;

至於為什麼只有非靜態的成員函式才能定義 成虛函式??

我還沒搞清楚》之後再研究研究

下面是對上面所說的虛函式編寫時所要注意的地方(對上面的總結)

1、派生類重寫基類的虛函式實現多型,要求函式名、引數列表、返回值完全相同。(協變除外)

2、基類中定義了虛函式,在派生類中該函式始終保持虛函式的特性。(就像是上面說的函式test2)

3、關於哪些函式可以定義為虛函式,只有類的非靜態成員函式才能定義為虛函式,靜態成員函式不能定義為虛函式。(建構函式除外 )

4、建構函式不能定義為虛函式,雖然可以將operator=定義為虛函式,但最好不要這麼做,使用時容

易混淆5、如果在類外定義虛函式,只能在宣告函式時加virtual關鍵字,定義時不用加(宣告和定義只在乙個地方加上virtual)

6、不要在建構函式和析構函式中呼叫虛函式,在建構函式和析構函式中,物件是不完整的,可能會

出現未定義的行為。(因為虛函式是通過虛表來呼叫的,構造與析構時,物件不完整)。

7、最好將基類的析構函式宣告為虛函式。(析構函式比較特殊,因為派生類的析構函式跟基類的析構

函式名稱不一樣,但是構成覆蓋,這裡編譯器做了特殊處理)

C 多型解析

今天我們,來將將c 的三大特性之一的 多型性 為什麼會有這個呢?因為,我們編寫 時,有的時候,當物件不同時,就需要呼叫不同的函式。在這個時候就需要使用的多型了。再說類的多型性之前我先來說說物件這個概念。物件的概念可以分為兩種型別 所謂的靜態型別,就是一般的型別 而動態型別,舉個例子來說就像是賦值相容...

C 多型繼承解析

在c 中,類的概念是最重要的,類就是實物的乙個模版,或是一種抽象的方法和資料的封裝,每用類宣告乙個變數,那我們就叫做類的例項化,在類的生存區域,會呼叫建構函式,在臨界區則會呼叫析構函式,構造的物件在記憶體中的表示就是類中的資料成員依次構造,如class string 在記憶體中這個string類共有...

C 基礎解析之 多型

今天繼續和大家一起 c 我們今天來聊聊c 中物件導向中乙個重要的特性 多型 簡單的一句話解釋多型 相同的方法呼叫可以實現不同的實現方式。通俗的說多型就是不同的表現形式,比如 中國人吃飯用筷子,歐洲以及北美都用刀叉,還有一些另類的人種直接上手,雖然他們的行為方式不同,但是他們有乙個目的就是吃飯!說白了...