動態(tài)綁定

動態(tài)綁定

  1. 對象的靜態(tài)類型:對象在聲明時采用的類型,在編譯期確定,靜態(tài)類型無法更改
  2. 對象的動態(tài)類型:所指對象的類型,在運(yùn)行期決定。對象的動態(tài)類型可以更改,
  3. 靜態(tài)綁定:綁定的是對象的靜態(tài)類型,發(fā)生在編譯期
  4. 動態(tài)綁定:綁定的是對象的動態(tài)類型
class B{
public:
    void doSomething() {
    }
    virtual void vfun() {
    }
};
class C : public B{
public:
    void doSomething() {//子類中是一個非虛函數(shù),這樣會造成名稱遮擋
    }
    virtual void vfun() {
    }
};
class D : public B {
public:
    void doSomething() { }//子類中是一個非虛函數(shù),這樣會造成名稱遮擋
    virtual void vfun() {  }
}

D* pD = new D();
B* pB = pD;
// pD和pB都指向同一個對象,但是doSomething()是no-virtual函數(shù),是靜態(tài)綁定的
// 編譯期會根據(jù)對象的靜態(tài)類型來選擇函數(shù)
pD->doSomething(); //調(diào)用的是D::doSomething()
pB->doSomething(); //調(diào)用的是B::doSomething()
//由于vfun是虛函數(shù),它是動態(tài)綁定的,雖然pD,PB的靜態(tài)類型不同,但是指向同一個對象
// 動態(tài)類型是相同的,都是D*,所以它倆調(diào)用的是同一個B::vfun()。
pD->vfun();
pB->vfun();

哪些是動態(tài)綁定哪些是靜態(tài)綁定:
只有當(dāng)使用指針或者引用時調(diào)用虛函數(shù)才使用動態(tài)綁定,其他的全是靜態(tài)綁定。

缺省參數(shù)是靜態(tài)綁定的。
具有繼承關(guān)系的類之間發(fā)生類型轉(zhuǎn)換:

  1. 從派生類向基類的類型轉(zhuǎn)換只對指針或引用有效
  2. 基類向派生類不存在隱式類型轉(zhuǎn)換
  3. 派生類向基類的類型轉(zhuǎn)換可能會由于訪問受限存在問題
#include <iostream>
using namespace std;
//class A final { } final 關(guān)鍵字可以防止繼承的發(fā)生
class A {
    public:
        A() =default;
        virtual void f() const {
            cout << "A::f()" << endl;
        }
        virtual ~A() {}
};

class B : public A {
    public:
        B() =default;
        void f() const override{ // C++11 中使用override來說明派生類中的虛函數(shù),方便清晰定位
            cout << "B::f()" << endl;
        }
        ~B(){}
};

void call(A &i){ //這里使用基類作為形參的引用,可以處理派生類和基類,實(shí)現(xiàn)代碼復(fù)用,OOP
    i.f();
}

int main()
{
    B b;// B的內(nèi)存分布中,虛函數(shù)表位于函數(shù)指針位置起始位置,B中的f()覆蓋了基類的f()指針,
    A a;
    A *pB = new B;
    call(b); // 調(diào)用b的f()
    call(a); //調(diào)用 a的f();
    delete pB; 
// 先如果基類的析構(gòu)函數(shù)是虛函數(shù),則先調(diào)用基類的析構(gòu)函數(shù),在調(diào)用派生類的析構(gòu)函數(shù),如果基類的析構(gòu)函數(shù)不是虛函數(shù),則只析構(gòu)基類造成泄露。
// 但是對于局部變量離開作用域,則是先調(diào)用派生的析構(gòu)函數(shù),然后在調(diào)用基類的析構(gòu)函數(shù)

// b是局部變量,析構(gòu)的時候不是動態(tài)綁定,因此會依次調(diào)用~B,~A。
// 但pB是A類型的,在使用delete時如果A的析構(gòu)函數(shù)不是虛函數(shù),則會只調(diào)用A的析構(gòu)函數(shù),造成子類的內(nèi)存泄露
// 而如果A的析構(gòu)函數(shù)是虛函數(shù),由于存在動態(tài)綁定,并且通過指針或者引用,存在派生類向基類轉(zhuǎn)換則,delete會在調(diào)用完~A,發(fā)現(xiàn)~A是虛函數(shù),再調(diào)用~B,完成全部的析構(gòu)。

    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容