数学建模社区-数学中国

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

作者: 蕾欧娜    时间: 2015-4-17 09:51
标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?
[backcolor=white !important][size=1em]
[size=1em][size=1em]  class, w/ |4 Z# j! Q
[size=1em]      InterfaceU13 w3 g' x+ h* C: {3 c
[size=1em]  {
. p9 ]. i6 z8 L) @( c* S[size=1em]  public:. Q4 b, O: T: f# u! J' A: t
[size=1em]      virtual void func1() = 0;2 r% v9 Q: D+ n- S
[size=1em]  }9 a" w4 P  `1 @6 }5 r! N

8 q7 |  w: }3 r, ~[size=1em]  class
( s, Y4 [9 m! v  B, u5 M$ U[size=1em]      InterfaceU2
- M. v! r9 b/ T, ^, `[size=1em]  {/ O0 y4 D. d4 W$ Y# i3 q
[size=1em]  public:/ j2 d( a# z' g  M, M1 d. a6 y
[size=1em]      virtual void func2() = 0;: j+ s2 k; A1 B6 o7 `9 F" W
[size=1em]  }$ @; U4 _  x' _/ W

# `/ t' z: O: r+ k1 ]% w[size=1em]  class
0 T5 P& u5 H+ ]/ A! f[size=1em]    Wrapper
6 @6 }3 S" y; q[size=1em]  {
# B/ z8 N# S- Y7 W! R( ^[size=1em]  public:
5 b9 F" Q6 k0 s# J[size=1em]      virtual InterfaceU1* getInterface1() = 0;
8 n; x: ~; t4 s, r; Y* X: C* X[size=1em]      virtual InterfaceU2* getInterface2() = 0;. }+ e; T) ^' T3 m: h  c
[size=1em]  }
( b7 }3 K' i0 I( J# q! v. T9 _/ L- L1 W
[size=1em]  class
  N, i  N* a4 s9 U* ][size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2
' D. V  u9 D/ \4 a; j2 R  w* b[size=1em]  {  V! A2 F$ h1 A5 S4 ]
[size=1em]  public:
" T8 m+ A; N9 L  R- V+ G% ]) X0 b6 O[size=1em]      virtual InterfaceU1* getInterface1()2 m0 p1 ~& Q4 [% P- B) P/ v
[size=1em]      {! J$ q6 V/ h/ w9 p2 p1 a
[size=1em]          return this;
1 O$ u% `& p) x[size=1em]      }) |  I7 T# A! ]5 Q7 `
[size=1em]      virtual InterfaceU2* getInterface2()
/ a+ u  G$ x, N% w* `[size=1em]      {4 T7 H1 c) M4 v) N3 L) p
  d5 v0 ?4 H" a
[size=1em]          return this;0 o  Y# S% U6 t, @  t, |: Z9 K
[size=1em]     }# ~3 z, {& p3 t+ R% s4 u6 K* [
[size=1em]     virtual void func1()
: Z# c. ?9 v* g/ V[size=1em]     {/ w$ B$ N, l" D. n7 T. V9 q+ t
[size=1em]         printf("%s", "func1");
' M5 t% I/ q% }; B% e; V5 U[size=1em]     }
7 m: G, ~# i* v, r6 ^5 j- f; B& k) {& |3 r# R$ d- o" s
[size=1em]     virtual void func2()- r9 i. W1 H7 j5 r6 T  B
[size=1em]     {
/ [# ^) ?  F9 f# Z2 H. z[size=1em]        printf("%s", "func2");$ O8 o% t2 n9 H! i% W
[size=1em]     }1 d$ f- I; q3 z7 k0 U
[size=1em] }
3 M1 E6 P: Q9 P4 v4 g0 w- U4 ?; `7 t- \

, C3 q) A5 S0 y6 \, Q
( w8 @- V: l9 ^+ x

- o' a6 p/ [, Q假设有如下代码:# M3 E! Y# J- s
[backcolor=white !important][size=1em]PHP code
( j; d& ~* c  M# G
[color=white !important][size=1em]?

) M) F0 [4 F) k" K" F8 T
[size=1em]1
4 h! \( N+ D& k1 D1 ~
[size=1em]2
  l( \7 c9 p( y& ?4 Y% m. v7 U
[size=1em][size=1em]Base* pBase = new Base();1 u+ Q0 E. t2 t9 c+ ?6 N
[size=1em]pBase->getInterface1()->func1();
- Z* h! Z  z2 m" y6 m" g
1 J* A) e4 M( r& |! I
4 p  v/ B8 R, d) U! u

0 ^  s  O' T$ C5 }; Q( T2 L7 ]4 z- j: M. `: b& i) k/ R7 k/ D
其实以上代码等于:
- M# o+ P" V* `$ L# j5 K4 M8 w[backcolor=white !important][size=1em]PHP code1 K7 O, J8 z3 z8 {9 a
[color=white !important][size=1em]?
' W1 _& k( ?! _* I* Z. B
[size=1em]1

- \9 J6 a. s2 C- z; D
[size=1em]2
$ B' G$ u2 P0 U: D+ L, f9 Z
[size=1em]3
6 B; z$ c: j; p+ K4 f) P
[size=1em][size=1em] Base* pBase = new Base();
) O& b" W2 V$ L% W: W3 v[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();2 H1 R% z7 O# U
[size=1em] pInterface1->func1();
& c* c: q% _5 ]% Q. B4 g0 o3 p+ X7 e& t0 k

9 H! I# f' P8 m& z6 ^0 f8 O) L) \+ f( T5 M/ {

) ?: w0 X3 c  w- w3 ]; a0 m" V
4 D  ]$ J& U& e2 N+ H
! c. y, [0 g7 J0 j! r1 L              C++编译后,Base类的虚函数表如下:
9 C6 V; p: B3 B% D! A$ |[backcolor=white !important][size=1em]         PHP code# ]4 |. P. P: f0 C
[color=white !important][size=1em]?

/ x8 u7 s$ J% k5 [) [
[size=1em]1
7 i: G4 B( T# Y- @  x, g# S# q
[size=1em]2
/ `% i: I' c* [0 K
[size=1em]3

* `2 w0 L6 ~- x3 U
[size=1em]4
- l$ `$ ?, |, V" z7 N  d3 l
[size=1em][size=1em]  ) {  i0 E2 H5 T- [
[size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|5 R6 f! ~1 B  t* O, ]
[size=1em]  vTable:InterfaceU1 |Base::func1()|( e  R9 G' G% u
[size=1em]  vTable:InterfaceU2 |Base::func2()|
) D' q+ A; t' K$ R8 M! a  V
4 ^2 z1 \. q* {; O8 ^8 H, ~( |
. N5 p9 R( H0 `7 B- }

, F9 L( y# p$ ?( h8 ]* B
& u0 p  ~- [( J) R: ^) N) n, C% k" _0 w- E* R. {
     如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。
" {3 A' R  d! A7 y    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。  J4 w3 Y$ T/ B
    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?+ x" T7 Z6 j9 C: d4 l. y1 X
    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)0 P, b; D7 m! X/ {$ ?, _$ l

% P; J- d3 c( @# S" b




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