数学建模社区-数学中国

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

作者: 蕾欧娜    时间: 2015-4-17 09:47
标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?
[backcolor=white !important][size=1em]
[size=1em][size=1em]class0 b/ i7 |, C/ G# v9 y* K2 z
[size=1em]    InterfaceU1, Q8 S8 k, t/ M( w
[size=1em]{
% P+ x9 ~. `5 V( ?( c[size=1em]public:
; o% e$ ^! w6 W8 `8 B[size=1em]    virtual void func1() = 0;
: P; _( ^* e, U7 i; i% t; a[size=1em]}# Q8 O7 C" D5 J
: e6 C3 }/ q( ]1 K1 k
[size=1em]class! N7 ~" ]4 {, h- v3 ~1 v+ n
[size=1em]    InterfaceU2+ ~1 L' s+ d8 j0 P! r
[size=1em]{# N4 ?5 d. x1 t" W$ p
[size=1em]public:
- k! e6 ^  d% r' F[size=1em]    virtual void func2() = 0;
! T8 R1 ~# I1 v4 `! V$ e8 J[size=1em]}) \+ B8 b) `6 C4 r8 o
" F- k" b, h3 y/ a. b9 ~; h
[size=1em]class
1 N% ^5 }' [8 x[size=1em]    Wrapper
3 Q/ I1 o4 H% \/ [( Z9 ]7 O8 u[size=1em]{
3 M6 U/ w6 K, r$ c[size=1em]public:, `8 S" E* R! M. k3 D" R
[size=1em]    virtual InterfaceU1* getInterface1() = 0;
- F! y0 E* l5 }0 ^: T6 C[size=1em]    virtual InterfaceU2* getInterface2() = 0;
* M* j0 l. N! B4 N! e& D9 |0 s[size=1em]}2 J: j+ Y6 e, K: o; |& _

- O* J" s8 i! B5 l[size=1em]class( p1 i0 h7 m) _
[size=1em]    Base : public Wrapper, public InterfaceU1, public InterfaceU2
' P3 R5 i* h6 F[size=1em]{
9 O! p- J, K' O5 \3 y! C( d' s6 u7 m[size=1em]public:7 y8 s. H. K6 o' a+ [
[size=1em]    virtual InterfaceU1* getInterface1()
+ I* o$ z; W+ D+ J[size=1em]    {' p  K" [5 e* O1 x: l
[size=1em]        return this;2 b& O" x- Q. h- n1 ^
[size=1em]    }
8 b2 Q  Y7 U2 c. N; n# x[size=1em]    virtual InterfaceU2* getInterface2()! P& i8 n4 ]9 O# b
[size=1em]    {
6 v. p8 q! l$ R: o5 X4 h" l0 ?. X7 Z! H- z. e2 H% K( v, W
[size=1em]        return this;( Y9 A% E0 c3 R" R/ r( N# K  i
[size=1em]    }. G6 o: t: N4 O7 z, A# a3 P
[size=1em]    virtual void func1()0 [3 N0 @1 W0 p9 ^# Y7 b. V
[size=1em]    {
( e4 B/ M8 O) R[size=1em]        printf("%s", "func1");
! e$ R! T+ t5 g' G7 v  |[size=1em]    }
  j9 E, f7 n' c# ?- F
& z( E+ l, C. V+ a0 o[size=1em]    virtual void func2()
+ m( n4 _# v' Z& r3 A, K& r( N4 v[size=1em]    {
1 C% V/ H% [' N% ]3 A) X  h[size=1em]        printf("%s", "func2");
) {, @! |+ ]9 g* J[size=1em]    }+ O$ n" A, H9 s. D' v1 `
[size=1em]}
8 d0 b  y3 i' z: l
, H$ j& D* P* k/ l  W& b

& d0 s% j2 }  s- i$ y6 O3 i- J

* h1 J* p6 R8 V1 b3 ]1 t8 N+ i& n7 Q  g7 N
假设有如下代码:. g9 u7 I+ d9 b: Q; {
[backcolor=white !important][size=1em]PHP code
( F5 w6 T3 }! {# _
[color=white !important][size=1em]?
: K' U' K( R" K
[size=1em]1

( f* a3 S& ^9 `% Y' q
[size=1em]2

* m! X2 n: C8 i% Z- R% A
[size=1em][size=1em]Base* pBase = new Base();
  ]/ K1 l: o: i5 u$ A- A[size=1em]pBase->getInterface1()->func1();# q. i5 ^0 m3 U/ Y
' u0 ?7 r! [! D; @% G, t) c* S

' k3 b1 N0 u7 Q- [) ^3 G( L, B/ t' ^/ j  a! O' B2 _+ s

5 d" l' s6 \# N" h其实以上代码等于:
3 @) d; N$ u& I[backcolor=white !important][size=1em]PHP code
) r+ X; X( q. l5 e/ X; m
[color=white !important][size=1em]?

3 h4 k5 c0 z! }) Z* r
[size=1em]1
( _- F* ?2 ]) L
[size=1em]2
! b8 h, G3 \) }& t- P9 }9 P: z
[size=1em]3

0 C8 C( o) h+ z( v
[size=1em][size=1em]Base* pBase = new Base();
* u& ~6 H% F1 a% ~  g4 Q6 ~* f[size=1em]InterfaceU1* pInterface1 = pBase->getInterface1();
1 @( z/ x' {/ p6 _& h- a- d7 V9 _( W[size=1em]pInterface1->func1();6 r1 V5 L* w) _4 c

: C, t. i. |+ k& i

6 A/ h7 j) K8 u" O4 `. b8 H% |- T/ q6 F# H& D
, K8 M& m4 `# r* J( X6 _

6 w! ?* K4 d+ |  t4 f2 U
" b) y- p' g9 N  ~& r8 VC++编译后,Base类的虚函数表如下:8 e* {0 g- B6 T, }; f* Y0 s& b
[backcolor=white !important][size=1em]PHP code: @: i3 h, Y3 T9 @/ ~% a9 C& L9 B
[color=white !important][size=1em]?

5 b3 F4 h- p+ M4 Y$ N
[size=1em]1

. V* u3 i( q4 k. Z% ]
[size=1em]2
" A/ v( K1 ^, O2 w2 P# G! E
[size=1em]3
) K# K$ j, T* ]/ C
[size=1em]4
  C! g* j  s7 x4 ~0 J
[size=1em][size=1em]  + ?0 C5 I+ u' C
[size=1em]vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|" q! J* K* w# `" Y6 `5 C
[size=1em]vTable:InterfaceU1 |Base::func1()|
, [& A- T% k3 g# z9 J[size=1em]vTable:InterfaceU2 |Base::func2()|
$ U3 Z. F  U8 T0 ~" v$ U4 Z/ l! w" R8 P# p) _
. T% z) k, C. p4 l( k

! J3 v- N. R' e& q4 l: _: w) c) ?7 {7 s

: }6 c4 z& \& ]( [; r% ^: Q如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。
2 a' E8 D; }1 x( _# p' {. P/ {3 d但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。
5 |3 ~. L7 X" R. M  i$ \C++是如何得到当前应该使用vptr[??]位置的函数地址呢?' X. f2 G" v" o- T( v7 q
C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)' e$ ?7 T" k# T; F
3 j7 X3 d: C" N1 k7 P/ J$ J





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