数学建模社区-数学中国

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

作者: 蕾欧娜    时间: 2015-4-17 09:51
标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?
[backcolor=white !important][size=1em]
[size=1em][size=1em]  class
8 `9 w1 Z0 y1 t9 x# K2 V& ?+ e[size=1em]      InterfaceU1
1 P$ ~& ~4 ?& a[size=1em]  {
/ V# L9 ]/ ~( m* Y) i[size=1em]  public:
" P; V/ ^  b* p1 l3 p# B" v5 h! q[size=1em]      virtual void func1() = 0;
, g9 r' b8 w1 a4 Q* ?) u[size=1em]  }
" F- J! ]% `. h9 k8 J' P
& |! Y; l0 }* m1 H1 n' U& U[size=1em]  class; P0 _/ z0 c/ G7 V) ~
[size=1em]      InterfaceU2. Y8 ~+ J$ c! ~2 w2 N
[size=1em]  {
9 B) E& B' `8 [. [) J: F1 m( e[size=1em]  public:
, c9 t3 x- |6 v) T[size=1em]      virtual void func2() = 0;; ~% V4 i% R6 y# }; b5 ?3 T
[size=1em]  }
4 y4 x/ ?6 Q! o! I+ M9 z- Y/ z! B( B2 v& I8 L( a
[size=1em]  class
+ [8 r( {4 n9 U  u* _7 P+ Q[size=1em]    Wrapper
* t: {: y- x" B8 N+ c1 d[size=1em]  {
# u$ k7 |/ w1 T2 c! Z[size=1em]  public:: h: t# f* t, W' p3 K1 }" r$ S
[size=1em]      virtual InterfaceU1* getInterface1() = 0;
' {) a9 K+ K, V: Z/ b4 r[size=1em]      virtual InterfaceU2* getInterface2() = 0;6 H7 Q* N6 }: x: r6 h4 o! y" |* i
[size=1em]  }4 F/ \$ {- f. n, d3 Z( z

3 u1 J4 \( X6 e/ w' x[size=1em]  class
9 W5 B$ b; z) [[size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2
  p  I8 D) N0 y* \3 q" w4 k2 O[size=1em]  {
+ c$ z" a, P- v5 H6 H[size=1em]  public:
; |, g5 N/ A7 D8 X& L5 s[size=1em]      virtual InterfaceU1* getInterface1()
7 l2 l# t0 S5 x[size=1em]      {
( p+ w9 [( G. m  A2 g  {# e% L9 ?8 f1 S[size=1em]          return this;
! n* H! k, \$ l[size=1em]      }
0 A" [1 \" X& J6 M/ d3 Z[size=1em]      virtual InterfaceU2* getInterface2()
6 }# x6 f  H0 \  ^: F[size=1em]      {0 R8 B* \; K$ e; @
2 ^% d" p2 m! y) ~. m
[size=1em]          return this;3 o. M% K# S' ?. N: L" n+ |! I
[size=1em]     }
' T. X  A* {; p& v* f. p" y& O[size=1em]     virtual void func1()1 l7 ^5 U, {9 I' m% ^2 T3 z
[size=1em]     {2 n# T! S9 x7 o
[size=1em]         printf("%s", "func1");
+ r9 ^" l4 ]! ^6 k4 W[size=1em]     }. ]& z  d: i( [7 |" x; V
- T: m* b  g, ?+ T, r* w( E( ~9 j
[size=1em]     virtual void func2(): Q8 |( }5 i, X% a2 }
[size=1em]     {. G  |; V1 B7 Z5 I0 c
[size=1em]        printf("%s", "func2");: p$ g! `6 F5 c6 Y# Y. m
[size=1em]     }* I) @, B! i6 `4 b  o8 n
[size=1em] }- m& W1 D% p$ p( a" K
" C( v/ y) g8 l7 x/ d2 ^8 p
/ K9 L; |1 q4 O; K% D2 _$ m( q
2 I6 x( p; z+ E3 s  b7 m  [
% {; Q0 R! w9 Y. N# V  w$ I* V
假设有如下代码:8 n$ p. K# S* u8 r1 G# e
[backcolor=white !important][size=1em]PHP code
2 a! }( ~7 u+ m
[color=white !important][size=1em]?
5 Q2 n5 h! S, f6 u
[size=1em]1

, b1 z# H% Q8 v) w& X, f# Z1 x5 I
[size=1em]2

- Z' g2 y+ B9 `; `
[size=1em][size=1em]Base* pBase = new Base();- I& v( J* g* u) z
[size=1em]pBase->getInterface1()->func1();
/ w* f( k- r/ e. [5 x- H
* {- N! u3 H' P! k) u* ?/ z0 f& n
5 P4 v$ Z/ b6 W: A* B5 q" ]2 F
* t1 z7 D% K/ S2 k8 w+ r- v
1 v, U4 s/ ^% Z( ]4 t4 w
其实以上代码等于:/ B+ n$ c' P9 a  U! e5 E1 q9 D
[backcolor=white !important][size=1em]PHP code
2 G- D2 {8 l$ [3 ?
[color=white !important][size=1em]?
1 ~6 t1 X$ E* c) e
[size=1em]1

" Q% }; I, J. l( T
[size=1em]2
  p. t7 z* k  ~+ U1 B: D/ \0 X: K
[size=1em]3
( Z* @7 @7 K4 m- ~3 x1 U
[size=1em][size=1em] Base* pBase = new Base();( B) A9 Q# n8 x. o" `
[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();
5 N/ U( n6 d1 F1 t2 W/ p- o5 x# g[size=1em] pInterface1->func1();6 q1 q% C8 |, `& Y$ y
1 J6 x. n1 z7 A3 X6 M
3 R: M+ @! m* S% K: X* `0 ?: ~
( Z- p6 i* d; f

5 X9 x4 x, r1 V5 K2 W2 T8 H2 Q$ y, H2 M' G; W* }
' U, q, b5 T. _. a. M" [6 O
              C++编译后,Base类的虚函数表如下:
$ ~+ @- T% e( x" d3 t[backcolor=white !important][size=1em]         PHP code7 @9 ^3 k9 `) b7 S/ T* v* t
[color=white !important][size=1em]?

5 f" T9 a3 V* R$ G- F; b
[size=1em]1
( O# x8 O/ m- D. E% Q8 y, g3 J
[size=1em]2
+ h% L8 [# {# U" [
[size=1em]3
7 t) r7 x7 [2 I/ g7 f& {7 y; P4 z
[size=1em]4
, {  q/ J+ ^+ O' {- A% {. {
[size=1em][size=1em]  1 s9 ^+ |; v# f! w
[size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|0 Y! y. w. W( m" A6 Q- r
[size=1em]  vTable:InterfaceU1 |Base::func1()|5 [! ]* m- m9 S2 d3 L
[size=1em]  vTable:InterfaceU2 |Base::func2()|5 V( K4 c$ x, ~2 a" V
3 a, T7 i' n# V3 @! i/ l
7 L. b- ]8 [" l
; J- W( H' z5 ?' H1 [2 m

. g5 E! X3 I% b& b8 S0 S! s  M& t+ n, f1 H) ?- s0 O
     如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。2 v; ~; }6 g. s; _( A
    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。
: P7 L7 r6 B5 w! r4 n) n    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?) a7 M5 r0 p$ p" }6 c0 R4 B
    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)/ G1 Y: G& L1 Y3 `
9 R% F7 j/ N: |





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