数学建模社区-数学中国

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

作者: 蕾欧娜    时间: 2015-4-17 09:51
标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?
[backcolor=white !important][size=1em]
[size=1em][size=1em]  class5 L% D5 y6 f6 V: q
[size=1em]      InterfaceU1+ _4 T; w3 ]& |6 D" f
[size=1em]  {
. f* e: s  B9 m: G$ B3 O[size=1em]  public:& P5 e/ l: k; A9 K+ g8 D
[size=1em]      virtual void func1() = 0;6 U1 ?$ I& m, W, n/ a
[size=1em]  }$ u& ^' K/ s$ |" E+ J
7 `/ ]9 ]9 p1 d* y" N% z9 v+ v8 p7 Z+ U
[size=1em]  class
/ R0 ~% i' ?$ ]& a9 Z[size=1em]      InterfaceU2* E5 m5 J3 |# }( a4 L# _3 O
[size=1em]  {
0 h' M5 Z" {/ y! Y. i9 K[size=1em]  public:! e: T. J6 m6 f% t6 O/ ?  o
[size=1em]      virtual void func2() = 0;
" L+ Q* Q+ ^$ \: u" [[size=1em]  }( C5 |9 D& M2 G/ A: |

. ?( `$ {' m. S5 `6 j2 a" w[size=1em]  class, n; p; y) l% I6 ]
[size=1em]    Wrapper- O0 c8 t5 ?+ j* k" B
[size=1em]  {
% R# l# v* N7 A) Q3 W" m1 K[size=1em]  public:
/ w0 R& \6 b, G9 k[size=1em]      virtual InterfaceU1* getInterface1() = 0;
& H5 P# [& F( ][size=1em]      virtual InterfaceU2* getInterface2() = 0;/ ~1 K5 v* P; {4 [- q1 V. b
[size=1em]  }
- t! \/ k* h+ [7 N
9 e% F7 Z9 @+ p[size=1em]  class  z( T  q& c' ]( k, T
[size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2
6 W. i6 [4 N& `* g[size=1em]  {. f2 @2 r3 D& `+ a+ K& S3 v7 `
[size=1em]  public:5 ]0 h0 D% c! i2 Q1 A
[size=1em]      virtual InterfaceU1* getInterface1()3 b5 J0 ^. A8 G9 e( T
[size=1em]      {2 f4 w1 i# {2 ]9 m9 x
[size=1em]          return this;
% A  k! L' ?% ?1 T! G7 V[size=1em]      }
2 u& P3 `& a6 `8 H[size=1em]      virtual InterfaceU2* getInterface2()
, l. Y7 _% {0 m3 _- w8 x/ A3 s[size=1em]      {
. L. W- F" ?! K1 Q" Z! M: b( d) e0 M  P
[size=1em]          return this;
% L+ S/ L. A1 }; L+ q5 Q) B[size=1em]     }" q' P0 Q( e% E$ v) j2 q
[size=1em]     virtual void func1()
/ ~4 \. B0 r  y  n! d1 I" j7 u4 f[size=1em]     {
7 W% p$ Q  I3 N; P0 e[size=1em]         printf("%s", "func1");
3 f1 b' F3 }. b0 Q3 [[size=1em]     }2 {  m) b3 y# Q, J+ ?

& i$ M# R- c% u) c[size=1em]     virtual void func2()+ A" F4 p: d/ B( T" o
[size=1em]     {5 f" v7 Q! @# I$ F
[size=1em]        printf("%s", "func2");
) Y. E$ c7 Z* {" f" T[size=1em]     }
, e" R3 b+ v4 T: H. y. G3 a[size=1em] }
/ L9 v. [- Q0 _* ~) R5 j) Q
& q, ]  m2 b  K( ~
3 M# |3 Y' O, o/ m% C3 {" @
4 D2 C/ J8 N" u% d: s4 V
4 w2 t: N+ [! e& X$ X
假设有如下代码:
8 Z5 e( F! p% ]$ ]0 u$ |' v' a[backcolor=white !important][size=1em]PHP code% V5 y* R+ o* S6 t3 }3 p
[color=white !important][size=1em]?

, u- \8 g7 G0 m6 s3 p2 D- @
[size=1em]1

; N" e9 O# K) r6 o4 e5 M2 v
[size=1em]2

4 H; a9 P% O# d6 N2 f
[size=1em][size=1em]Base* pBase = new Base();. n/ ]5 f( p( e, [- a* L  ?
[size=1em]pBase->getInterface1()->func1();
) |% ?) U- H8 ^* F, |- B0 a
8 {& a- \+ x1 @! b

% V4 A" Q1 T/ ?4 G5 T) J' z  I
" a. \& N# N1 w0 ?# U/ Z  [" w
其实以上代码等于:2 X% H# {3 D5 R& N: Y. k
[backcolor=white !important][size=1em]PHP code
( m3 j9 |0 e, D
[color=white !important][size=1em]?
; J7 B2 D; `: W1 u6 x4 p: _4 G
[size=1em]1
6 y; c0 t6 a6 ]" k: e7 c1 A
[size=1em]2

' @" h8 C, y$ M2 r
[size=1em]3
( c. S- c; _8 Y! l* o7 ~" ~+ _
[size=1em][size=1em] Base* pBase = new Base();
6 O0 S. O' b: h' F+ h& k[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();# Z7 X/ @  P# L" P3 E- ^5 k0 I$ H
[size=1em] pInterface1->func1();# j0 C; w! U, O# h7 t% ^
5 {$ E" F% M, _9 u5 z; V
* w+ d" }' N, p
. M6 P# P( ]6 A, X5 U* k
0 F8 a) O$ K( \( A% N, w9 T( Q! `7 w

: C2 g3 m7 ]% @- `% Q' g, ?$ K0 I+ g) s" W" _4 {9 M2 w$ M
              C++编译后,Base类的虚函数表如下:
% M) z: ]) c% c. ^5 x' _[backcolor=white !important][size=1em]         PHP code5 Y7 w& C, U: I5 S, C0 G
[color=white !important][size=1em]?

% Q2 j, M8 ~1 \$ z% w  t
[size=1em]1

# y& h6 }% C) F: R* _% ^
[size=1em]2

1 I% |/ i' e( ]/ q3 v
[size=1em]3
9 i, a$ p! Z* d6 o: c8 B: c
[size=1em]4
4 p6 G6 E- @9 p9 w
[size=1em][size=1em]  
- U! Q6 O+ o" i& U" i[size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|" z7 O5 D- R5 g/ L
[size=1em]  vTable:InterfaceU1 |Base::func1()|: |( l+ r( L+ d, W
[size=1em]  vTable:InterfaceU2 |Base::func2()|) H3 N8 p% h: `# S: x
7 c' ^* \+ W" X7 S9 h

! U/ U0 R7 r7 q2 w- j6 u9 q9 d7 t9 h6 B
( o) N6 b( _+ I; _
* g$ W$ c, S% z  j
     如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。, E% S" g: A$ C) F
    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。
' q, u. i7 z4 d& R0 @6 F    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?' ]% c) p: ^: Y7 M5 @
    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)
' V- g& ?% J/ e( u5 ]
1 P7 R" A; `; T% s% w




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