数学建模社区-数学中国

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

作者: 蕾欧娜    时间: 2015-4-17 09:47
标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?
[backcolor=white !important][size=1em]
[size=1em][size=1em]class
" h& v2 Z  W, \. o1 m6 F[size=1em]    InterfaceU1
9 _1 a6 u& p0 T! _2 _[size=1em]{# S+ u, z  g$ F" f6 {6 y
[size=1em]public:
! Z3 w6 P6 d" R% i% `[size=1em]    virtual void func1() = 0;
& Q" j1 V; r5 j( f[size=1em]}0 A0 i) D- h! ~$ t. [
) q9 `9 t% S+ e( B- r/ }
[size=1em]class
( {* m0 Z$ K7 M[size=1em]    InterfaceU2. ]' [$ c5 ~: ?. j
[size=1em]{
+ @1 ]  q& O8 ~[size=1em]public:
" K! Q8 o" P9 Z) }* Q[size=1em]    virtual void func2() = 0;+ B# W. G, c- F
[size=1em]}" \8 z) G$ |) I- z) Z

' T8 X6 p. l! z) t& ?/ @! F3 x[size=1em]class: T$ z# `. u+ |2 T. U; k( [) b0 C
[size=1em]    Wrapper
& ]" K! U9 Z3 e7 T' {[size=1em]{2 n8 T. b: \5 k% Q, B7 e
[size=1em]public:. h$ [1 e% h8 P( m' `
[size=1em]    virtual InterfaceU1* getInterface1() = 0;1 H( J3 l4 P3 N6 s
[size=1em]    virtual InterfaceU2* getInterface2() = 0;
4 q  h- G5 g& {# o4 }[size=1em]}8 L/ J1 E' T% k7 g
9 u1 Q  u- d0 E5 k; O
[size=1em]class' B8 x  _" c, H6 y
[size=1em]    Base : public Wrapper, public InterfaceU1, public InterfaceU26 s2 c6 N2 G6 }! R4 a& D  @
[size=1em]{
5 Y! A: q: x9 [0 O( j! |[size=1em]public:6 G1 F5 R' H3 `4 g, ?
[size=1em]    virtual InterfaceU1* getInterface1()
  y, b, x5 q4 L  D[size=1em]    {
' X3 s! Q; f# Y* I, l& \- J[size=1em]        return this;0 N8 b; C$ |( f  Z; d+ ^
[size=1em]    }
: W# w% C" X/ \: _, r( F[size=1em]    virtual InterfaceU2* getInterface2()
  l( \, ~9 o) p- C4 v' W. S" F, |[size=1em]    {
, x* C* B. \# A  n7 W% e5 v8 T- `0 a' @0 ?
[size=1em]        return this;
. G! h6 y5 T5 m1 l% }[size=1em]    }+ Z) I9 W0 ?# b+ n4 r( T4 T1 b
[size=1em]    virtual void func1()
0 L/ t8 q$ R6 J5 M6 E" o8 }[size=1em]    {
( {( J2 f, U  j[size=1em]        printf("%s", "func1");' Y' ^& |$ W. L% ]- {
[size=1em]    }5 \6 L* g. A4 g4 J
) l. u* {  L9 n/ v* ]
[size=1em]    virtual void func2()
! ^8 X) L9 M6 \# l3 _$ B/ Z[size=1em]    {6 V) b- d+ r6 d: e8 {8 Q  C. O
[size=1em]        printf("%s", "func2");" V% s) p. k, H% e# D
[size=1em]    }6 S0 R6 `" {% U8 [' b0 P, t+ k
[size=1em]}
/ F5 ^% {& U; f+ n+ `6 m* K: r/ o) Q# q3 Q7 d" O' H5 t
- |, V+ C7 D# h) Q% z0 |

9 w" N$ Q# H* g" H% a+ @% q4 m
4 n/ ]/ P) B" M. |假设有如下代码:% I! r: M* o: t8 g+ r2 w
[backcolor=white !important][size=1em]PHP code6 C3 G( C% K3 A- ^# F( H- Y
[color=white !important][size=1em]?

, p# M6 V! a5 X& B, B
[size=1em]1
# q! V) ]* j% x6 O$ H& r
[size=1em]2

% U" c" V7 ^# i) t8 c
[size=1em][size=1em]Base* pBase = new Base();( q, I) f: U  Z0 V+ y
[size=1em]pBase->getInterface1()->func1();
! y; K0 w. b& ~: D% j0 V6 Q' A- N( o

2 _: I2 J! a; E* M5 g: `4 ]" M3 H8 O) c, `3 A$ B
- w) S+ i( R' H9 x+ i
其实以上代码等于:
7 ~& C' y/ j% L# S3 W7 f' y3 h[backcolor=white !important][size=1em]PHP code
# t( g0 K5 |) i; ^; a
[color=white !important][size=1em]?
3 F6 G2 [; u* H% K( Y
[size=1em]1
  }: c' _+ Q( X# B1 L  A
[size=1em]2
/ W: h5 T( Q( W& o. u
[size=1em]3
6 y8 W: M1 a/ V" L, ^! j0 q; D
[size=1em][size=1em]Base* pBase = new Base();
1 j8 `, w! f3 a3 h4 E' f% k[size=1em]InterfaceU1* pInterface1 = pBase->getInterface1();
, W) ]8 x* x' J' _; U[size=1em]pInterface1->func1();0 v" d7 {5 Q1 X3 ]5 t# e4 |; |$ u

, L  e+ G% `. V; U( Y  p5 s

! Q1 ?9 T& L; l0 L) ^$ h5 u& {, D: ?7 x# J$ Q
5 b( g5 n; t1 I7 ~+ @

/ T" Y$ g2 o& _3 T6 L% n0 C/ W
+ n' F8 M7 Y- OC++编译后,Base类的虚函数表如下:7 j0 `! x& |! _8 N1 Z- f% s
[backcolor=white !important][size=1em]PHP code! r$ E0 G9 `" ~3 c7 k
[color=white !important][size=1em]?
" `/ m5 y0 ?; ?. L
[size=1em]1
2 F; W4 w# z! \7 k( r! o3 ~0 z
[size=1em]2
1 z. s% V. Z! n0 G% F) ?* \! c
[size=1em]3
( p! a1 K* h2 n' {
[size=1em]4
4 H9 x* ?! _0 y: B8 l5 z, p( z  i2 d
[size=1em][size=1em]  
, E  x- X$ X3 a* u5 z  _0 W7 b+ |[size=1em]vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|$ X2 ]  J$ ^  ~# [. Z! g
[size=1em]vTable:InterfaceU1 |Base::func1()|+ m* X, ]. T/ B4 b" p, B
[size=1em]vTable:InterfaceU2 |Base::func2()|
7 y0 V, M1 P. N+ L. k5 k! _
4 x0 A' i" p7 I) F( k9 b9 V! c
0 C9 B: P6 i+ L; v5 Z3 [0 b4 S! g

! e0 B2 T( j+ S8 o& b6 U* d, R
: p/ |1 t6 A) `2 z" f& a+ I, l9 r- j
如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。5 n, z+ a! \& m9 {2 M6 l( D, z: N
但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。
9 T+ n. {& g/ N. m$ H/ ]! wC++是如何得到当前应该使用vptr[??]位置的函数地址呢?; r& I- k0 s. O  d% a
C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)
/ x- o4 \& b. _8 s# M1 `" N$ y6 A, l7 @





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