多態(1)—— 多態的定義、多態的三個必要條件、靜態聯編和動態聯編、虛析構函數、重載重寫重定義


1、多態的意義

  如果有幾個上似而不完全相同的對象,有時人們要求在向它們發出同一個消息時, 它們的反應各不相同,分別執行不同的操作。這種情況就是多態現象。

  C++中所謂的多態(polymorphism)是指,由繼承而產生的相關的不同的類,其對象對同一消息會作出不同的響應。

2、多態的三個必要條件

  • 要有繼承
  • 要有虛函數重寫
  • 要有父類指針(父類引用)指向子類對象
#include <iostream>
#include <string>
using namespace std;

class Yuebuqun
{
public:
    Yuebuqun(string kongfu)
    {
        this->kongfu = kongfu;
    }
    virtual void fight()//表示修飾一個成員方法是一個虛函數,必要條件2
    {
        cout << "岳不群" << "使用了" << this->kongfu << endl;
    }

    string kongfu;
};

//林平之繼承了岳不群
class Linpingzhi :public Yuebuqun
{
public:
    Linpingzhi(string kongfu) :Yuebuqun(kongfu)
    {
    }

    //如果說父類中有一個虛函數是fight(),子類如果去重寫這個虛函數,
    //那么如果傳遞進來的是子類,調用子類的fight,如果傳遞進來的是父類,調用父類的fight
    void fight()//必要條件2
    {
        cout << "林平之" << "使用了" << kongfu << endl;
    }
};

//令狐沖繼承了岳不群
class Linghuchong :public Yuebuqun
{
public:
    Linghuchong(string kongfu) :Yuebuqun(kongfu)
    {
    }

    void fight()
    {
        cout << "令狐沖" << "使用了" << kongfu << endl;
    }
};

//在全局提供一個打斗的方法
void fightPeople(Yuebuqun *hero)//必要條件3,相當於Yuebuqun *hero = xiaopp;或Yuebuqun *hero = xiaoyy; //或Yuebuqun *hero = xiaoll;
{ hero->fight();//希望如果傳遞進來的是子類,調用子類的fight; //如果傳遞進來的是父類,調用父類的fight //這種行為就是多態行為
} //多態發生的三個必要條件:
//1.要有繼承
//2.要有虛函數重寫
//3.父類指針或引用指向子類對象
int main(void)
{
    Yuebuqun *xiaoyy = new Yuebuqun("葵花寶典");
    xiaoyy->fight();

    Linpingzhi *xiaopp = new Linpingzhi("辟邪劍譜");
    xiaopp->fight();

    Linghuchong *xiaoll = new Linghuchong("獨孤九劍");
    xiaoll->fight();

    //多態的實現
    fightPeople(xiaoyy);//岳不群使用了葵花寶典
    fightPeople(xiaopp);//林平之使用了辟邪劍譜
    fightPeople(xiaoll);//令狐沖使用了獨孤九劍
    //編譯器默認做了一個安全的處理,編譯認為不管傳遞時子類對象還是父類對象,
    //如果統一執行父類的方法,那么一定可以被成功執行。

    delete xiaoyy;
    delete xiaopp;
    delete xiaoll;

    return 0;
}

 3、靜態聯編和動態聯編

(1)聯編是指一個程序模塊、代碼之間互相關聯的過程。

(2)靜態聯編,是程序的匹配、連接在編譯階段實現,也稱為早期匹配。重載函數使用靜態聯編。

(3)動態聯編是指程序聯編推遲到運行時進行,所以又稱為晚期聯編(遲邦定)。switch語句和if語句是動態聯編的例子。

1、C++與C相同,是靜態編譯型語言;
2、在編譯時,編譯器自動根據指針的類型判斷指向的是一個什么樣的對象;所以編譯器認為父類指針指向的是父類對象;
3、由於程序沒有運行,所以不可能知道父類指針指向的具體是父類對象還是子類對象,從程序安全的角度,編譯器假設父類指針只指向父類對象,因此編譯的結果為調用父類的成員函數。這種特性就是靜態聯編;
4、多態的發生是動態聯編,實在程序執行的時候判斷具體父類指針應該調用的方法。

 4、虛析構函數

  • 構造函數不能是虛函數。建立一個派生類對象時,必須從類層次的根開始,沿着繼承路徑逐個調用基類的構造函數。
  • 析構函數可以是虛的。虛析構函數用於指引delete運算符正確析構動態對象。

5、重載重寫重定義

重載(添加)
a、相同的范圍(在同一個類中)
b、函數名字相同
c、參數不同
d、virtual可有可無
重寫(覆蓋) 是指派生類函數覆蓋基類函數,特征是:
a、不同的范圍,分別位於基類和派生類中
b、函數名字相同
c、參數相同
d、基類函數必須有virtual關鍵字
重定義(隱藏) 是指派生類的函數屏蔽了與其同名的基類函數,規則如下:
a、如果派生類的函數和基類的函數同名,但是參數不同,此時,不管有無virtual,基類的函數被隱藏。
b、如果派生類的函數與基類的函數同名,但是參數也相同,但是基類函數沒有virtual關鍵字,此時,基類的函數被隱藏。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM