日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【C++深度剖析教程27】多态的概念与意义

發布時間:2023/12/10 c/c++ 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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、函數重寫

    • 子類中可以重定義父類中已經存在的成員函數
    • 這種重定義發生在繼承中,叫做函數重寫
    • 函數重寫是函數同名覆蓋的特殊情況

    那么當函數重寫遇上賦值兼容會發生什么?
    先來看一個簡單的例子:

    #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);}void print(){cout << "I'm Parent." << endl;} };class Child : public Parent { public:int mv;void add(int x, int y, int z){mv += (x + y + z);}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); // Expected to print: I'm Parent.how_to_print(&c); // Expected to print: I'm Child.return 0; }

    運行結果為:
    I’m Parent.
    I’m Parent.

    很顯然,這個結果并不是我們想要的,我們想要的是執行 how_to_print(&c); 后打印I’m Child.
    這就是函數print重寫后,遇到賦值兼容的情況。

    問題分析:

    • 編譯期,間編譯器只能根據指針的類型判斷所指向的對象
    • 根據賦值兼容,編譯器認為父類指針指向的是父類對象
    • 因此,編譯結果只可能是調用父類中定義的同名的函數

    小結:

  • 子類對象可以當做父類對象使用(賦值兼容)
  • 父類指針可以正確的指向子類對象
  • 父類引用可以正確的代表子類對象
  • 子類中可以重寫父類的成員函數
  • 3、解決辦法-多態的概念

    • 父類中被重寫的函數依然會繼承給子類
    • 子類中被重寫的函數會覆蓋父類中的同名函數

    而面向對象期望的行為是:

    • 根據實際的對象類型調用具體的成員重寫函數
    • 父類指針(引用)指向
      *父類對象,則調用父類中定義的函數
      *子類對象,則調用子類中定義的重寫函數

    要實現這個行為,就需要引出面向對象中的多態的概念:
    面向對象中多態的概念:
    - 根據實際的對象類型,決定函數調用的具體目標
    - 通用的調用語句,在實際的運行中有多種不同的表現形態

    C++語言直接支持多態的概念

  • 通過使用virtual關鍵字對多態進行支持
  • 被virtual聲明的函數被重寫后具有多態性
  • 被virtual聲明的函數叫做虛函數
  • 修改上一個程序:

    #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、總結

  • 函數重寫只可能發生在父類與子類之間
  • 根據實際對象的類型調用具體的函數,多態性
  • virtual關鍵字是C++中支持多態的唯一方法
  • 被重寫的虛函數可以表現出多態性
  • 想獲得各種學習資源以及交流學習的加我:
    qq:1126137994
    微信:liu1126137994
    可以共同交流關于嵌入式,操作系統,C++語言,C語言,數據結構等技術問題。

    總結

    以上是生活随笔為你收集整理的【C++深度剖析教程27】多态的概念与意义的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。