天天看點

C++多态之動态綁定

動态綁定:

定義:

動态綁定是将一個過程調用與相應代碼連結起來的行為。是指與給定的過程調用相關聯的代碼,隻有在運作期才可知的一種綁定,它是多态實作的具體形式。

原理:

C++中,通過基類的引用或指針調用虛函數時,發生動态綁定。引用(或指針)既可以指向基類對象也可以指向派生類對象,這一事實是動态綁定的關鍵。用引用(或指針)調用的虛函數在運作時确定,被調用的函數是引用(或指針)所指對的實際類型所定義的。

C++中動态綁定是通過虛函數實作的。而虛函數是通過一張虛函數表實作的。這個表中記錄了虛函數的位址,解決繼承、覆寫的問題,保證動态綁定時能夠根據對象的實際類型調用正确的函數。

在C++的标準規格說明書中說到,編譯器必需要保證虛函數表的指針存在于對象執行個體中最前面的位置(這是為了保證正确取到虛函數的偏移量)。這意味着我們通過對象執行個體的位址得到這張虛函數表,然後就可以周遊其中函數指針,并調用相應的函數。

缺點:

1.動态綁定在函數調用時需要在虛函數表中查找,是以性能比靜态函數調用稍低。

2.通過基類類型的指針通路派生類自己的虛函數将發生錯誤。

虛函數、動态綁定、運作時多态之間的關系:

虛函數是動态綁定的基礎;動态綁定是實作運作時多态的基礎。

動态綁定兩個條件:

(1) 隻有虛函數才能進行動态綁定,非虛函數不進行動态綁定。

(2) 必須通過基類類型的引用或指針進行函數調用。

對應的有靜态綁定

靜态綁定是指不需要考慮表達式的執行期語義,僅分析程式文本而決定的表達式類型。靜态綁定僅依賴于包含表達式的程式文本的形式,而在程式運作時不會改變。簡單的講,就是上下文無關,在編譯時就可以确定其類型。

動态綁定與靜态綁定

靜态綁定:編譯時綁定,通過對象調用

動态綁定:運作時綁定,通過位址實作

示例:

#include <iostream>
using namespace std;
class Base
{
public:
    virtual void f1()
    {
        cout<<"Base"<<endl;
    }
};
class Drived1:public Base
{
public:
    void f1()
    {
        cout<<"Drived1"<<endl;
    }
};
class Drived2:public Base
{
public:
    void f1()
    {
        cout<<"Drived2"<<endl;
    }
};
void Test(Base* pB)
{
    pB->f1 ();
}
int main()
{
    Base b;
    Drived1 d1;
    Drived2 d2;
    Test(&b);
    Test(&d1);
    Test(&d2);
    return ;
}
           

輸出結果:

Base

Drived1

Drived12