80 likes | 96 Views
仮想函数と仮想基底 ( その 2). 2019.08.20 長谷川啓. B. B が D の基底. vftbl of B. B::vfptr. B part. B* pb; D* pd; pb = pd;. pb := pd + offset(B). D. vftbl of D. D::vfptr. B::vfptr. vftbl of B の内容を D で override. B part. D で宣言された仮想函数のテーブル. D part. D. vftbl of D. B1 と B2 が D の基底. D::vfptr. B1.
E N D
仮想函数と仮想基底(その2) 2019.08.20 長谷川啓
B Bが Dの基底 vftbl of B B::vfptr B part B* pb; D* pd; pb = pd; pb := pd + offset(B) D vftbl of D D::vfptr B::vfptr vftbl of Bの内容を D で override B part Dで宣言された仮想函数のテーブル D part
D vftbl of D B1と B2が Dの基底 D::vfptr B1 vftbl of B1 B1::vfptr B1::vfptr B1 part offset(B2) B1 part B2::vfptr B2 part B2 vftbl of B2 B2::vfptr B2 part D part B1* pb1; B2* pb2; D* pd; pb1 = pd; pb2 = pd; pb1 := pd + offset(B1) pb2 := pd + offset(B2)
vbtbl of D D struct D : virtual B1, B2, virtual B3, B4, virtual B5 { // ... }; B2* pb2; B5* pb5; D* pd; pb2 = pd; pb5 = pd; D::vbptr offset(B1) delta(B5) D::vfptr offset(B3) B2::vfptr offset(B5) B2 part vftbl of D B4::vfptr B4 part D part B1::vfptr B1 part pb2 := pd + offset(B2) t0 := (int**)pd; t1 := *t0 t2 := t1 + delta(B5) t3 := *t2 pb5 := pd + t3 B3::vfptr B3 part B5::vfptr B5 part
菱形継承 • struct D1 : B1, virtual VB { • // ... • }; • struct D2 : B2, virtual VB { • // ... • }; • struct DD : D1, D2 { • // ... • }; B1 VB B2 D1 D2 DD
vbtbl of D2 vbtbl of D1 D2 D1 y x D2::vbptr D1::vbptr vftbl of D2 vftbl of D1 D2::vfptr D1::vfptr B2::vfptr B1::vfptr y x B2 part B1 part D2 part D1 part VB::vfptr VB::vfptr VB part VB part
DD vbtbl of DD DD::vfptr D1::vbptr x’ D1の vbtblの値や D2の vbtlb の値が override されている D1::vfptr y’ B1::vfptr D1* pd1; D2* pd2; VB* pvb; DD* pdd; pd1 = pdd; pd2 = pdd; pvb = pdd; B1 part vftbl of DD x’ D1 part D2::vbptr D2::vfptr B2::vfptr B2 part y’ D2 part pd1 := pdd + offset(D1) pd2 := pdd + offset(D2) pvb := pdd + offset(VB) この変換では vbtblは参照 されない DD part VB::vfptr VB part
vbtblと vftbl • DD の vbtblのサイズ • 以下の和: • D1 の vbtblのサイズ • D2 の vbtlbのサイズ • DD の仮想基底の個数(DDの場合は 0) • DD の vftblのサイズ • 以下の和: • D1 の vftblのサイズ • D2 の vftblのサイズ • DD で virtual 宣言された函数の個数 • V の vftblのサイズ