数学建模社区-数学中国

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

作者: 蕾欧娜    时间: 2015-4-17 09:51
标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?
[backcolor=white !important][size=1em]
[size=1em][size=1em]  class
: ~4 M) |6 H1 g: |[size=1em]      InterfaceU1
: N5 a( j; D. }3 \7 [[size=1em]  {; n: B& q9 a1 X1 [0 C
[size=1em]  public:
" c* z" W$ b7 ][size=1em]      virtual void func1() = 0;
9 ?: t5 p: C  [. t  l$ S9 v6 P[size=1em]  }
9 c+ o9 f2 ?8 m* _& O6 }6 L( `1 g3 L# w7 A
[size=1em]  class
1 |" Z/ ?4 y( `" V[size=1em]      InterfaceU2
2 V! q8 f' u3 n; l! p; |6 [, @[size=1em]  {
' q- q2 S( w) {; s/ C9 v[size=1em]  public:
* A- s6 d3 O* p( _3 \& ?5 v[size=1em]      virtual void func2() = 0;: b3 {6 H: K# t4 L1 ]
[size=1em]  }8 [& H% x1 p. v* e( T( j
2 n' p+ L  r9 w- T* f
[size=1em]  class5 b7 ]+ t' V! }' T  y
[size=1em]    Wrapper
) l  q- r$ S! C2 P/ n5 n[size=1em]  {
3 l. Y  g( @; j' _' f" p3 ][size=1em]  public:2 E6 B$ d8 H- ]! l: D) ]0 G
[size=1em]      virtual InterfaceU1* getInterface1() = 0;* F" `! e1 W: j
[size=1em]      virtual InterfaceU2* getInterface2() = 0;
1 h- ^3 @  R4 Y9 J9 I5 G6 i5 L+ U; b[size=1em]  }& y3 d8 n( t  J' i
3 h" ^+ }, L" K1 M
[size=1em]  class9 {( a: z3 |$ U& w1 Z: E
[size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2* \& j. N% \# u3 U) s$ |; {( G$ p
[size=1em]  {
7 J. U+ q9 V: J* |8 L[size=1em]  public:  O  x0 f$ n9 }1 |( F  h
[size=1em]      virtual InterfaceU1* getInterface1()) F/ k: ^9 i) \' o. T
[size=1em]      {
9 ~2 a- C6 ~4 E" W3 O[size=1em]          return this;
( p: R" T( `1 j+ F- b; t: l[size=1em]      }9 B* C8 ?" i! q6 t; T$ [
[size=1em]      virtual InterfaceU2* getInterface2()
3 }  }2 K  s7 q, }( a' i[size=1em]      {2 B5 x" H8 s+ }0 K$ K  r
+ P- S' Q& [$ T# p$ }4 \- M
[size=1em]          return this;/ Q" E7 p- ]4 D  G4 \1 Q1 ]4 z
[size=1em]     }8 u4 c8 \% w. r# ]: T; ?* h
[size=1em]     virtual void func1()
0 {; L$ }+ K5 A; S1 t[size=1em]     {7 N+ d) j* D; l: r
[size=1em]         printf("%s", "func1");
, `- I( N7 p2 W" G% u# e, R[size=1em]     }" O9 S# D; F/ T, V6 [) R# j
) O+ l- I9 P" K5 S
[size=1em]     virtual void func2()
8 W1 J' ^0 O/ a( m9 a' M; p[size=1em]     {
* o% `/ l8 k4 l: k0 f[size=1em]        printf("%s", "func2");
. d3 j* S$ R* _. D[size=1em]     }: C; c3 h! O: U' M
[size=1em] }; M- d( w! W- a! b6 K2 \

& a+ F- E  b9 w& |5 }2 W% ?/ O
7 p: x/ m) R2 E( m# {% ?+ t$ X

% x4 Q8 E' D" u  m( e0 V% F; U8 r$ j9 m
假设有如下代码:
9 A. i1 ~$ F1 [[backcolor=white !important][size=1em]PHP code
5 s4 k' G# ~6 T( {
[color=white !important][size=1em]?
; u  `0 k! T& q% \$ X+ H- ^
[size=1em]1

1 `6 _3 J1 Y9 i' j. V' d
[size=1em]2
/ X+ F2 X0 O1 n+ i. m$ r
[size=1em][size=1em]Base* pBase = new Base();) m+ Y1 C# _/ o) G& c
[size=1em]pBase->getInterface1()->func1();
9 L2 Q8 r+ n1 e3 a) o$ D1 J2 E- W* X2 p! w) ?" O1 z4 R

5 J  ]! d% U1 Y
$ I3 b2 R/ `# [) h  m9 }: D
7 c! l: y  `4 f7 j其实以上代码等于:
/ ~+ l3 J' k1 m8 q; d[backcolor=white !important][size=1em]PHP code, I" [% `- \, K9 u) a
[color=white !important][size=1em]?
- b1 G/ g2 y2 |1 L3 x9 u
[size=1em]1
& R% V+ P' }) ?% u/ _
[size=1em]2

" C+ ?" T7 L# y# w, b
[size=1em]3

- Q- U0 O& I6 Y7 w, I( ?
[size=1em][size=1em] Base* pBase = new Base();0 r( w' O  y& b6 Z; c
[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();$ o0 e8 O% n3 M& Y3 |
[size=1em] pInterface1->func1();
4 W2 D% U& h) a
2 y4 R5 D* X8 V3 Q# x+ X
6 S5 l7 ]/ H  D! r! J1 c" l6 D

) E& }, _5 y  T/ w0 x/ M& g! j* C: J3 V/ ^4 |' k. y* J
' Q. n/ B  |  G: m
, k+ g, e' x4 h$ v
              C++编译后,Base类的虚函数表如下:) [5 D5 P" J. K. ^! f" n
[backcolor=white !important][size=1em]         PHP code
( e' N* d5 L5 [; S% @! d
[color=white !important][size=1em]?

0 ^8 u6 F( K- e+ B3 m7 \
[size=1em]1

- U! _$ d* U: ~# p7 b
[size=1em]2
5 g2 `) v  {7 x9 t
[size=1em]3
; \# N* q9 B1 F$ Z) x7 q0 n+ v
[size=1em]4

) P: H0 b7 y& v" P0 D( L7 C; F1 R
[size=1em][size=1em]  5 T0 m, L. r/ n! L/ I8 M
[size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|
  _0 B& o( [2 |7 ?4 I6 u[size=1em]  vTable:InterfaceU1 |Base::func1()|
  e) ^- C( E. w: ^1 x& x[size=1em]  vTable:InterfaceU2 |Base::func2()|7 c, }; G, w# x- M  V# Q

: U3 V! D+ u  t* t3 m% a6 c
- x2 }) t: X! o0 Q/ J7 `
4 S8 t' r4 y% t3 Y% H$ x: C
2 s% G. z  u& C9 K  r1 W
3 Q5 Q; w( w! N
     如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。; U: E: W7 _8 c
    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。
* P4 x6 L( p$ ]. |+ Z/ V* q8 ~    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?
: ^$ W. S) a3 K, l    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)' k6 H3 A$ q2 F- `8 S
) k0 r5 Z4 `, r! \8 `





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