class a;};
class b::public a
};class c::public a
};下面逐步分析測試**及結果,
c* pc = new c(); //pc的靜態型別是它宣告的型別c*,動態型別也是c*;
b* pb = new b(); //pb的靜態型別和動態型別也都是b*;
a* pa = pc; //pa的靜態型別是它宣告的型別a*,動態型別是pa所指向的物件pc的型別c*;
pa = pb; //pa的動態型別可以更改,現在它的動態型別是b*,但其靜態型別仍是宣告時候的a*;
c *pnull = null; //pnull的靜態型別是它宣告的型別c*,沒有動態型別,因為它指向了null;
如果明白上面**的意思,請繼續,
pa->func(); //a::func() pa的靜態型別永遠都是a*,不管其指向的是哪個子類,都是直接呼叫a::func();
pc->func(); //c::func() pc的動、靜態型別都是c*,因此呼叫c::func();
pnull->func(); //c::func() 不用奇怪為什麼空指標也可以呼叫函式,因為這在編譯期就確定了,和指標空不空沒關係
如果注釋掉c中的fun()
public c::public a;
pa->func(); //a::func() 理由同上;
pc->func(); //a::func() pc在類c中找不到func的定義,因此到其基類中尋找;
pnull->func(); //a::func() 原因也解釋過了;
class a
}; pa->func(); //b::func() 因為有了virtual虛函式特性,pa的動態型別指向b*,因此先在b中查詢,找到後直接呼叫;
pc->func(); //c::func() pc的動、靜態型別都是c*,因此也是先在c中查詢;
pnull->func(); //空指標異常,因為是func是virtual函式,因此對func的呼叫只能等到執行期才能確定,然後才發現pnull是空指標;
如果乙個函式指標有靜態和動態型別時,(1)如果動態型別是虛函式則直接呼叫虛函式,如果沒有虛函式再去掉靜態型別 (2)如果靜態類中沒有要調的函式,則去基類中調,其實實質就是個誰先誰後呼叫的問題。
C 靜態繫結和動態繫結
c 為了支援多型性,才用了動態繫結和靜態繫結。首先理解四個名詞 1.物件的靜態型別 物件在宣告時採用的型別,是在編譯期確定的。2.物件的動態型別 目前所指物件的型別,是在執行期決定的。class b class c public b class d public b d pd new d pd的靜態...
靜態繫結和動態繫結
c 中,非虛函式都是靜態繫結,而虛函式卻是動態繫結。為了能夠更清楚地了解靜態繫結與動態繫結,我們可以看下面這個例子 include using namespace std class b 那麼兩次呼叫fun 函式是否相同呢?當然,如果d中沒有定義fun 函式 如例子中 那麼兩次呼叫的行為肯定會是一樣...
靜態繫結和動態繫結
物件的靜態型別 物件在宣告是採用的型別,在編譯期確定 物件的動態型別 當前物件所指的型別,在執行期決定,物件的動態型別可以更改,但靜態型別無法更改。靜態繫結 繫結的是物件的靜態型別,某特性 比如函式 依賴於物件的靜態型別,發生在編譯期。動態繫結 繫結的是物件的動態型別,某特性 比如函式 依賴於物件的...