数学建模社区-数学中国

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

作者: 蕾欧娜    时间: 2015-4-17 09:51
标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?
[backcolor=white !important][size=1em]
[size=1em][size=1em]  class
9 V% x0 V+ p. ?6 o* x4 W[size=1em]      InterfaceU1
2 g0 \( }& J& \! b[size=1em]  {$ C, d$ N0 Q$ \# w0 x+ X2 d% O9 f
[size=1em]  public:8 N6 t7 K  K* R. u8 y# I, v9 ]
[size=1em]      virtual void func1() = 0;; }: u5 k, j- Y
[size=1em]  }
& i  ^# @* e% j5 x$ D8 W" B4 P0 H) [1 w1 O3 b; s
[size=1em]  class' X: K# z5 T, M1 J5 M
[size=1em]      InterfaceU2
# t- S7 g4 o5 d+ J[size=1em]  {
& X3 a- H  P9 g: b[size=1em]  public:7 C0 h" g! O" g5 C& M
[size=1em]      virtual void func2() = 0;
6 k. i# G" Y% ^) k, j[size=1em]  }
+ W: @4 D: \" a$ I+ ~( X
% \0 o4 m! b2 K5 t- P2 \4 Y' A[size=1em]  class
# Z" Q2 e# Z2 q! Z' y# {& E[size=1em]    Wrapper
1 W4 @9 _+ ~1 C/ j* S, n[size=1em]  {
, C" }2 @8 `$ g- N+ L. \; ^[size=1em]  public:
9 M1 k+ o; L7 i& U[size=1em]      virtual InterfaceU1* getInterface1() = 0;9 E. q8 h0 j3 w4 F" P" F$ P2 N
[size=1em]      virtual InterfaceU2* getInterface2() = 0;) P7 o" E7 U8 M2 |
[size=1em]  }
" P) p6 F+ x* R( z2 d/ _* J2 S+ L. `) D8 I& e+ }) g
[size=1em]  class0 }$ @2 g9 z" Q; D
[size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2
$ O4 N- n, X  }' N[size=1em]  {
/ B3 w  Z- i5 p0 \% y+ D, p[size=1em]  public:
1 k% k% A/ p% X) P[size=1em]      virtual InterfaceU1* getInterface1()
. l2 ]7 x: y; J2 T/ ^) a. N[size=1em]      {
0 |/ ?8 r8 |; N[size=1em]          return this;0 R% ~9 {9 R9 h3 b: g8 d
[size=1em]      }
. w- I. c8 X2 |* x7 Q[size=1em]      virtual InterfaceU2* getInterface2()
4 {9 p9 i# b" z  W" ?[size=1em]      {
- y. Z& U6 `* w) b; V$ A4 i: f- k- q" f/ y) O) h
[size=1em]          return this;- v* ^: `4 Q: f/ D) ~2 @* g
[size=1em]     }3 q+ n6 F, L( J9 z
[size=1em]     virtual void func1()3 _: `! \5 D# A  C0 j" s( J
[size=1em]     {9 D( c/ [+ K" C& `$ \- s% e( M
[size=1em]         printf("%s", "func1");
$ k' X- l9 i5 ?0 K; g[size=1em]     }
% Q: w8 E: X0 Q! T; c9 G# D' n- G5 ~& A6 g% S) C; U4 R
[size=1em]     virtual void func2()/ I3 a7 Y( a$ U. e0 O3 O" ~/ s
[size=1em]     {% A! ?2 e5 p3 I2 ]
[size=1em]        printf("%s", "func2");
( B+ J& K0 j) @/ w7 T# x[size=1em]     }2 K# O0 r9 a( T3 P7 j# U
[size=1em] }6 `4 q5 @% O9 X! j0 W9 X6 q
3 ]( m1 e$ r+ |+ H9 O) \, Y! |8 u, ]
+ ^4 ^/ u& ^# ]4 y
$ a1 S2 e3 A$ H5 k7 D. @# s

: E/ [; t1 |$ n/ v# T- a' c( O1 b假设有如下代码:
# H& Y2 x7 \8 j# e( C& g+ n1 `[backcolor=white !important][size=1em]PHP code
& W  g5 }& y3 `9 |  A9 F: p7 S4 @1 I
[color=white !important][size=1em]?

9 a% C# v) M; l( I1 @
[size=1em]1

! e1 F1 r- x+ d9 y8 [$ l
[size=1em]2
. F# L! G5 y4 l# c
[size=1em][size=1em]Base* pBase = new Base();: P' |7 l" f3 t+ K2 n$ B# m6 A
[size=1em]pBase->getInterface1()->func1();
! p/ U" h2 w1 j  d% f6 m5 [! Q0 W
$ x; ?; @* H$ G! U/ D5 Q: ]
6 {) X/ B( T7 e0 ]

, `6 ~9 J7 m9 E
* F7 Z4 V3 [# B  z' o% u! ?其实以上代码等于:
' U) g2 r" b" Q0 L[backcolor=white !important][size=1em]PHP code  h- b& a+ B. E+ R7 ^0 o
[color=white !important][size=1em]?
5 @+ b. G& {/ j) v% b
[size=1em]1
4 b. e% v( E/ p
[size=1em]2

7 \6 `  v& t; t1 ^
[size=1em]3
/ x6 V, E5 ~8 R  g
[size=1em][size=1em] Base* pBase = new Base();9 F, @/ |( s. F7 p/ m
[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();5 y/ |+ s2 _, M0 N
[size=1em] pInterface1->func1();
' K  k1 B9 q' b% l7 x0 c/ P
+ L4 r- s+ s* u- W, w8 |

" m/ u" w, F3 q! D- N" ^' M8 c$ A9 f8 s" U

3 z2 L' s! |2 I) `- l: q3 _  X/ C" l  o0 P3 k! p
* z1 i+ [1 r- y
              C++编译后,Base类的虚函数表如下:
  U6 k! q; ?6 l5 Q/ c[backcolor=white !important][size=1em]         PHP code
  ^9 G- Q0 o# [2 `) R: S
[color=white !important][size=1em]?

- F) Z1 P" D0 l7 m0 y2 C
[size=1em]1
' J( y' M) n7 }8 D: K- V+ e* f
[size=1em]2
, g- t( T. T- L& A# R. ~2 b+ M
[size=1em]3

4 d( c" a  M' q5 E, O
[size=1em]4

. u9 H. C0 {4 F6 y. I
[size=1em][size=1em]  
0 b; B- }7 ]/ B2 {( A6 _, L[size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|
. k8 d) t' Y+ p: Y- z[size=1em]  vTable:InterfaceU1 |Base::func1()|
) N6 ^2 [+ q! ^. P: _8 Z1 [# ?% K[size=1em]  vTable:InterfaceU2 |Base::func2()|9 c0 z( |, Y. ]0 a# _
! i% u% [0 g' w
$ I4 D7 m" o; f1 C2 L2 a) K
2 ?' F3 r" T" ]: s8 s

4 J( _8 v" i1 ?3 D- a1 h
' f. W8 m, k% J  h1 P# q1 R# P     如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。6 J1 {/ G2 @2 p# j0 O/ N& L
    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。( r: p- Q6 u' x) k6 N9 ]4 n# d. m
    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?
/ O% z1 k+ N/ L! F1 W    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)
& A0 }0 c. m, U! i: G& W, G% h, b' N! Q8 s& s' B: h





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