多態的理解:
是一個物件導向新需求:
根據實際的物件類型來判斷重寫函數的調用
如果父類指標指向的是父類對象則調用父類中定義的函數
如果父類指標指向的是子類對象則調用子類中定義的重寫函數
解決方案:
Ø C++中通過virtual關鍵字對多態進行支援
Ø 使用virtual聲明的函數被重寫後即可展現多態特性
//物件導向3大概念
封裝
突破了C語言函數的概念。。
繼承
代碼複用 。。。。我複用原來寫好的代碼。。。
多態
多態可以使用未來。。。。。80年代寫了一個架構。。。。。。90年代人寫的代碼
多態是我們軟體行業追尋的一個目標。。。
//寫了一個架構,可以調用後來人,寫的代碼的能力
進一步的理解
//間接賦值成立的3個條件:
//1 定義兩個變數。。。
//2 建立關聯 。。。。
//3 *p
//多態成立的三個條件:
//1 要有繼承
//2 要有函數重寫。。。C 虛函數
//3 要有父類指標(父類引用)指向子類對象
//多態是設計模式的基礎,多態是架構的基礎
知識點1 虛解構函式
解構函式是為了釋放資源,
當釋放資源時有需求不能直接對對象釋放時如:
C *myC = new C; //C繼承B,B繼承A類
delete myC; //直接通過子類對象釋放資源 這種情況不需要寫virtual 關鍵字
需要通過父類指標將所有的子類都對象的解構函式都執行一遍
想通過父類指標 釋放所有的子類資源 (需要在最終父類的解構函式中加上virtual關鍵字)
void howtodelete(A *base){delete base; //這句話不會表現成多態 這種屬性}
知識點2:重載和重寫區別
函數重載
必須在同一個類中進行
子類無法重載父類的函數,父類同名函數將被名稱覆蓋(例如:父類中有函數a(),子類中也有函數a(),但是還有函數a(int b)這個函數就是重載父類函數產生錯誤!不能出現!)
重載是在編譯期間根據參數類型和個數決定函數調用
函數重寫
必鬚髮生於父類與子類之間
並且父類與子類中的函數必須有完全相同的原型
使用virtual聲明之後能夠產生多態(如果不使用virtual,那叫重定義)
多態是在運行期間根據具體對象的類型決定函數調用
例子分析:
//1 C++編譯器 看到func名字 ,因子類中func名字已經存在了(名稱覆蓋).所以c++編譯器不會去找父類的4個參數的func函數//2 c++編譯器只會在子類中,尋找func函數,找到了兩個func,一個是2個參數的,一個是3個參數的.//3 C++編譯器開始報錯..... error C2661: “Child::func”: 沒有重載函數接受 4 個參數//4 若想調用父類的func,只能加上父類的網域名稱..這樣去調用..c1.func(1, 3, 4, 5);//c1.func();//func函數的名字,在子類中發生了名稱覆蓋;子類的函數的名字,佔用了父類的函數的名字的位置//因為子類中已經有了func名字的重載形式。。。。//編譯器開始在子類中找func函數。。。。但是沒有0個參數的func函數
3 重點:
C++中多態的實現原理
當類中聲明虛函數時,編譯器會在類中產生一個虛函數表
虛函數表是一個儲存類成員函數指標的資料結構
虛函數表是由編譯器自動產生與維護的
virtual成員函數會被編譯器放入虛函數表中
存在虛函數時,每個對象中都有一個指向虛函數表的指標(vptr指標)
說明1:
通過虛函數表指標VPTR調用重寫函數是在程式運行時進行的,因此需要通過定址操作才能確定真正應該調用的函數。而普通成員函數是在編譯時間就確定了調用的函數。在效率上,虛函數的效率要低很多。
說明2:
出於效率考慮,沒有必要將所有成員函數都聲明為虛函數
說明3 :C++編譯器,執行HowToPrint函數,不需要區分是子類對象還是父類對象
以上就是C++複習要點總結之十——多態(一)的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!