多態按字面的意思就是多種形態。當類之間存在層次結構,並且類之間是通過繼承關聯時,就可能會用到多態。
C++多態就是當調用成員函數時,會根據調用函數的對象的類型來執行不同的函數。
一、靜態多態
我們以前說過的函數重載就是一個簡單的靜態多態,靜態多態是編譯器在編譯期間完成的,編譯器會根據實參類型來選擇調用合適的函數,如果有合適的函數可以調用就調,沒有的話就會發出警告或者報錯。
示例(book236.cpp)
/*
* 程序名:book236.cpp,此程序用於演示C++類的靜態多態。
* 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
#include <string.h>
class CGirl // 定義超女類
{
public:
char m_name[50]; // 姓名
int m_age; // 年齡
int m_height; // 身高,單位:釐米cm
char m_sc[30]; // 身材,火辣;普通;飛機場。
char m_yz[30]; // 顏值,漂亮;一般;歪瓜裂棗。
int Show() // 顯示超女基本信息的成員函數體
{ printf("姓名:%s,年齡:%d,身高:%d,身材:%s,顏值:%s\n",m_name,m_age,m_height,m_sc,m_yz); }
};
class CKCon:public CGirl // 定義王妃類,從超女類繼承
{
public:
char m_ch[50]; // 稱號
char m_palace[50]; // 居住的宮殿
int m_sal; // 奉祿
int Show() // 顯示王妃的稱號、宮殿和奉祿
{ printf("姓名:%s,稱號:%s,棲:%s,奉祿:%d兩銀子。\n",m_name,m_ch,m_palace,m_sal); }
};
int main()
{
CKCon KCon;
strcpy(KCon.m_name,"楊玉環"); KCon.m_age=28; KCon.m_height=168;
strcpy(KCon.m_sc,"火辣"); strcpy(KCon.m_yz,"漂亮"); strcpy(KCon.m_ch,"楊貴妃");
strcpy(KCon.m_palace,"華清宮"); KCon.m_sal=10000;
CGirl *pGirl; // 基類的指針
CKCon *pCon; // 派生類的指針
pGirl=pCon=&KCon; // 都指向派生類
pGirl->Show(); // 將調用的是基類的Show方法
pCon->Show(); // 將調用的是派生類的Show方法
}
運行效果
在book236.cpp的main函數中,創建的是CKCon對象,如果採用基類指針調用Show方法,變成了調用CGirl類的Show方法,而不是CKcon類的Show方法,因爲pGirl是CGirl的指針,pGirl->Show方法在程序編譯期間就已經設置好了。
二、動態多態
動態多態是在程序運行時根據基類的引用(指針)指向的對象來確定自己具體該調用哪一個類的虛函數。
讓我們對程序稍作修改,在CGirl類中,Show方法的聲明前放置關鍵字 virtual,如下所示:
virtual int Show() // 顯示超女基本信息的成員函數體
其它的代碼都不變,編譯並運行,結果如下:
此時,編譯器看的是指針的內容,而不是它的類型。這就是多態的一般使用方式。
三、虛函數
虛函數是在基類中使用關鍵字 virtual 聲明的函數,在派生類中重新定義虛函數。
我們想要的是在程序中可以根據所調用的對象類型來選擇調用的函數,這種操作被稱爲動態鏈接,或後期綁定。
四、純虛函數
我們可以在基類中只聲明虛函數,沒有函數的定義,在派生類中去實現函數的定義,這個時候就會用到純虛函數。
class CGirl // 定義超女類
{
public:
char m_name[50]; // 姓名
int m_age; // 年齡
int m_height; // 身高,單位:釐米cm
char m_sc[30]; // 身材,火辣;普通;飛機場。
char m_yz[30]; // 顏值,漂亮;一般;歪瓜裂棗。
virtual int Show()=0; // 申明一個純虛函數。
};
virtual int Show()=0;;告訴編譯器,函數只有聲明,沒有定義,是純虛函數。
五、C++ 接口(抽象類)
接口描述了類的行爲和功能,是標準和規範,而不需要完成類的功能實現。
C++接口是用抽象類來實現的,如果類中至少有一個函數被聲明爲純虛函數,則這個類就是抽象類。
設計抽象類的目的,是爲了給其他類提供一個可以繼承的基類。抽象類不能用於實例化對象,它只能作爲接口使用。如果試圖實例化一個抽象類的對象,會導致編譯錯誤。
如果一個基類的派生類需要實例化,則必須實現每個虛函數的定義,如果沒有在派生類中純虛函數的定義會導致編譯錯誤。
可用於實例化對象的類被稱爲具體類。
六、應用經驗
對初學者來說,類的多態、虛函數這些概念可能難以理解,因爲您想不到它的應用場景,在實際開發中,這些知識的應用場景也比較少,在一些大型的項目開發中纔可能用到,二十年來我只用過一次。
各位只要瞭解一下這些知識就可以了,掌握不了就算了。
七、版權聲明
C語言技術網原創文章,轉載請說明文章的來源、作者和原文的鏈接。
來源:C語言技術網(www.freecplus.net)
作者:碼農有道
如果文章有錯別字,或者內容有錯誤,或其他的建議和意見,請您留言指正,非常感謝!!!