数学建模社区-数学中国

标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置? [打印本页]

作者: 蕾欧娜    时间: 2015-4-17 09:51
标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?
[backcolor=white !important][size=1em]
[size=1em][size=1em]  class
+ O# L- ~$ T) d/ d, n- V  M[size=1em]      InterfaceU1
& R- Y2 B& @7 v  p, R3 a* r[size=1em]  {9 B  ^0 P" @" Z- S: m1 J
[size=1em]  public:  o3 C- A& _- E
[size=1em]      virtual void func1() = 0;
1 n5 d; y+ v' I: y+ A& p[size=1em]  }
: I$ ?7 p2 G0 |! _/ n! I3 ^" m  n. [  i' i& c- ]
[size=1em]  class# n/ `# Y& T4 E1 V7 G2 G0 }8 i) q
[size=1em]      InterfaceU2
! C+ f/ J2 q3 b# ^3 a  `4 p( m8 `4 _[size=1em]  {
' T) x% c# w2 s1 I[size=1em]  public:
$ W( @6 v' H* t1 c) d[size=1em]      virtual void func2() = 0;
: Z7 X# H# B- S" F[size=1em]  }
% \( J: T( \1 P; _2 b# q: H4 @( ?3 Q9 {$ a% U) C
[size=1em]  class
3 `: C" W& j9 G[size=1em]    Wrapper% W0 u( u: Q/ t; B
[size=1em]  {
2 d3 b7 y  @9 E/ b[size=1em]  public:5 `8 C$ c3 ^. e8 L1 }2 T9 q6 ]
[size=1em]      virtual InterfaceU1* getInterface1() = 0;
9 u" z; p1 G+ w% W$ Q[size=1em]      virtual InterfaceU2* getInterface2() = 0;
% G3 @4 A  t  s  o- Q, |$ k[size=1em]  }) m3 |. g5 \5 x  W6 D, x

3 S# {  ?+ Q; `  o) A- A, q% v) x[size=1em]  class
) `, T7 Q8 c$ l  C; |' L; E5 \! Q[size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2, H: A' S9 u6 I6 V$ N4 e
[size=1em]  {: h! ^; s" e/ K8 O8 s
[size=1em]  public:9 Z' Y. i+ k& t4 v: e4 n  h
[size=1em]      virtual InterfaceU1* getInterface1()( u4 K9 D1 U5 p" q' Y3 G: `9 j
[size=1em]      {
$ ^0 Z; r' J& ^7 V( \[size=1em]          return this;7 P0 L- F) N  p- H8 O2 B
[size=1em]      }
1 m8 `" U5 X8 A0 {+ u; w/ p: g( p[size=1em]      virtual InterfaceU2* getInterface2()
, e# E& a( h3 ?+ t8 b[size=1em]      {( J; g, D3 Y: {; D, L, @

7 ~% H' N2 |; E1 b& K4 C[size=1em]          return this;
5 I4 j$ V3 n4 `: F[size=1em]     }
. b. S1 h5 Z) C% c8 {" z# h( N[size=1em]     virtual void func1()
5 w8 E' x! n9 u4 }3 F, B! G' f! c[size=1em]     {! M/ z+ c* W4 _8 n, p5 u: {4 b$ |
[size=1em]         printf("%s", "func1");
9 G, j7 h4 r6 s  [; |[size=1em]     }5 @* m' n8 V5 w) M2 j  I! o
/ {1 u( j* \3 J: k" A$ h% M
[size=1em]     virtual void func2()
* h" t" [# u/ |2 B" G# M$ Q' k  q[size=1em]     {
! V4 ^4 g; ]& i0 y: l[size=1em]        printf("%s", "func2");
+ C% R7 U6 \. T# E, o[size=1em]     }
: M1 _+ b& B# `, l[size=1em] }
# c# g7 G2 J& k* F
; K! e! J2 Q( m# m2 n
& B  k6 ^9 D& S# v+ I) f

7 m) W6 t2 E: W; w9 X! U$ ~
/ t3 V, d/ c# x2 w! r假设有如下代码:
% @( Q0 f' W( T; T- ~6 R[backcolor=white !important][size=1em]PHP code6 ^0 ~) e: K% G, }9 x/ d
[color=white !important][size=1em]?

' s: [& b  l) i9 I7 D' M3 f
[size=1em]1
+ C' f0 N% E( W4 `
[size=1em]2

' s4 B9 N! @$ F6 @9 i9 n. b
[size=1em][size=1em]Base* pBase = new Base();
- l& i: X& x2 ^+ a6 V[size=1em]pBase->getInterface1()->func1();' v" a4 u. H9 r

7 K/ O* c) k* f# Y

" t5 H) F& K/ g+ V1 Z3 K$ `- t8 A
9 Z5 q: {2 D/ c+ v; B
其实以上代码等于:& ^* y+ I: _8 Q* R  T
[backcolor=white !important][size=1em]PHP code0 ^% E) \/ A/ E: g$ m2 \9 h- X! |
[color=white !important][size=1em]?

- A: r- h6 d( H6 i- F
[size=1em]1

) u/ }; _% j: C1 f- P
[size=1em]2
. {( q( b3 H( F3 O% A0 t- J' q
[size=1em]3

2 X) M, }5 D6 W, C! B
[size=1em][size=1em] Base* pBase = new Base();
! n" u% `8 H" ^3 g* s, p0 c* n$ |! |[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();
9 \* @. \% E- F+ I[size=1em] pInterface1->func1();
; R( ]; J+ ?2 S9 t; G. n
0 Z+ r/ h& E" u$ r

; E% W, ?' V7 i% e1 K
# S* J/ x; R2 n) y" E' u9 P* K
2 P& y  l  D+ [) a# f
. c/ R# j# o0 k- I5 a5 S4 N. y' y" ^: c! \% W1 i! B5 m
              C++编译后,Base类的虚函数表如下:
' F8 C. S, X% T6 t+ _[backcolor=white !important][size=1em]         PHP code
* u, J( `2 r8 w9 ^
[color=white !important][size=1em]?

. w0 U* ], K; A2 H: @7 p8 d& X6 Z
[size=1em]1

( j8 B9 x& J$ Q6 q' l
[size=1em]2
, `) w' w" Z0 Z# v( @: H/ p
[size=1em]3

% t2 Q$ j8 ]! s. m
[size=1em]4
, Z& ~3 T% @" s6 }
[size=1em][size=1em]  0 s4 ^+ c' r! e/ ^9 i0 G- X
[size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|5 n  l5 u8 x1 U6 U
[size=1em]  vTable:InterfaceU1 |Base::func1()|
0 H3 T4 b7 w7 r7 H7 ]. [[size=1em]  vTable:InterfaceU2 |Base::func2()|
2 @3 Q, ]4 D/ E& @2 l
5 Q' V" e8 O: C* D

" G0 e) f; j- n- ?9 \8 r6 s: E& o' k$ D7 e! `# _- n- @

  j% {) r8 U! L$ c) W; n6 ^
, i# T5 d5 H# S  B) _- C: P     如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。3 `+ J( ]6 @4 K# o8 r8 a( ^
    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。9 p" E2 T5 {  N0 i& K2 C
    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?
" `, f) D& {  W- U5 r' S    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)
( q! U# q: [$ p3 t: c9 y+ e) t4 p8 ^$ p' E





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5