【C++深度剖析教程27】多态的概念与意义
今天來學習一個新的概念,多態!!!多態在C++編程中具有重要的地位與意義,是面向對象的一個重要思想!
加qq1126137994一起學習更多技術~
1、問題引入
父類與子類之間具有賦值兼容性;
*子類對象可以當做父類對象使用(賦值兼容性)
看一個例子程序來理解一下:
#include <iostream> #include <string>using namespace std;class Parent { public:int mi;void add(int i){mi += i;}void add(int a, int b){mi += (a + b);} };class Child : public Parent { public:int mv;void add(int x, int y, int z){mv += (x + y + z);} };int main() {Parent p;Child c;p = c;Parent p1(c);Parent& rp = c;Parent* pp = &c;rp.mi = 100;rp.add(5); // 沒有發生同名覆蓋?rp.add(10, 10); // 沒有發生同名覆蓋?/* 為什么編譯不過? */// pp->mv = 1000; // pp是父類指針,指向子類c,那么c對象就退化為父類對象// pp->add(1, 10, 100); // pp只能訪問父類對象,并且可以訪問父類與子類同名的對象// 而不用指定作用域。return 0; }-當使用父類指針(引用)指向子類對象時
2、函數重寫
- 子類中可以重定義父類中已經存在的成員函數
- 這種重定義發生在繼承中,叫做函數重寫
- 函數重寫是函數同名覆蓋的特殊情況
那么當函數重寫遇上賦值兼容會發生什么?
先來看一個簡單的例子:
運行結果為:
I’m Parent.
I’m Parent.
很顯然,這個結果并不是我們想要的,我們想要的是執行 how_to_print(&c); 后打印I’m Child.
這就是函數print重寫后,遇到賦值兼容的情況。
問題分析:
- 編譯期,間編譯器只能根據指針的類型判斷所指向的對象
- 根據賦值兼容,編譯器認為父類指針指向的是父類對象
- 因此,編譯結果只可能是調用父類中定義的同名的函數
小結:
3、解決辦法-多態的概念
- 父類中被重寫的函數依然會繼承給子類
- 子類中被重寫的函數會覆蓋父類中的同名函數
而面向對象期望的行為是:
- 根據實際的對象類型調用具體的成員重寫函數
- 父類指針(引用)指向
*父類對象,則調用父類中定義的函數
*子類對象,則調用子類中定義的重寫函數
要實現這個行為,就需要引出面向對象中的多態的概念:
面向對象中多態的概念:
- 根據實際的對象類型,決定函數調用的具體目標
- 通用的調用語句,在實際的運行中有多種不同的表現形態
C++語言直接支持多態的概念
修改上一個程序:
#include <iostream> #include <string>using namespace std;class Parent { public:int mi;virtual void print(){cout << "I'm Parent." << endl;}};class Child : public Parent { public:int mv;void print(){cout << "I'm Child." << endl;} };void how_to_print(Parent* p) {p->print(); }int main() { Parent p;Child c;how_to_print(&p);how_to_print(&c);return 0; }運行結果:
I’m Parent.
I’m Child.
可以看出,這是我們想要的結果。
多態的意義:
4、多態在理論中的概念與意義
理論中的概念:
*在函數編譯期間就能確定具體的函數調用
-如.函數重載
*在程序實際運行后才能確定函數的具體調用
-如.函數重寫
給個例子說明:
#include <iostream> #include <string>using namespace std;class Parent { public:virtual void func(){cout << "void func()" << endl;}virtual void func(int i){cout << "void func(int i) : " << i << endl;}virtual void func(int i, int j){cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl;} };class Child : public Parent { public:void func(int i, int j){cout << "void func(int i, int j) : " << i + j << endl;}void func(int i, int j, int k){cout << "void func(int i, int j, int k) : " << i + j + k << endl;} };void run(Parent* p) {p->func(1, 2); // 展現多態的特性// 動態聯編 }int main() {Parent p;p.func(); // 靜態聯編p.func(1); // 靜態聯編p.func(1, 2); // 靜態聯編cout << endl;Child c;c.func(1, 2); // 靜態聯編cout << endl;run(&p);run(&c);return 0; }上述程序的運行結果為:
void func()
void func(int i) : 1
void func(int i, int j) : (1, 2)
void func(int i, int j) : 3
void func(int i, int j) : (1, 2)
void func(int i, int j) : 3
5、拓展訓練
下面是一個展現多態,繼承的程序,參考教學視頻第49課第二個視頻!
#include <iostream> #include <string>using namespace std;class Boss { public:int fight(){int ret = 10;cout << "Boss::fight() : " << ret << endl;return ret;} };class Master { public:virtual int eightSwordKill(){int ret = 8;cout << "Master::eightSwordKill() : " << ret << endl;return ret;} };class NewMaster : public Master { public:int eightSwordKill(){int ret = Master::eightSwordKill() * 2;cout << "NewMaster::eightSwordKill() : " << ret << endl;return ret;} };void field_pk(Master* master, Boss* boss) {int k = master->eightSwordKill();int b = boss->fight();if( k < b ){cout << "Master is killed..." << endl;}else{cout << "Boss is killed..." << endl;} }int main() {Master master;Boss boss;cout << "Master vs Boss" << endl;field_pk(&master, &boss);cout << "NewMaster vs Boss" << endl;NewMaster newMaster;field_pk(&newMaster, &boss);return 0; }運行結果為:
Master vs Boss
Master::eightSwordKill() : 8
Boss::fight() : 10
Master is killed…
NewMaster vs Boss
Master::eightSwordKill() : 8
NewMaster::eightSwordKill() : 16
Boss::fight() : 10
Boss is killed…
6、總結
想獲得各種學習資源以及交流學習的加我:
qq:1126137994
微信:liu1126137994
可以共同交流關于嵌入式,操作系統,C++語言,C語言,數據結構等技術問題。
總結
以上是生活随笔為你收集整理的【C++深度剖析教程27】多态的概念与意义的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux直播电视软件下载,周末了!通过
- 下一篇: php exist echo,PHP函数