数学建模社区-数学中国

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

作者: 蕾欧娜    时间: 2015-4-17 09:47
标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?
[backcolor=white !important][size=1em]
[size=1em][size=1em]class
# ]" M, O. z% N[size=1em]    InterfaceU1
4 g* {; m9 m# K6 ?[size=1em]{
% w1 |$ G6 c7 X; `[size=1em]public:0 {7 ~0 Q5 M3 b: i* d$ b2 ~% f5 u
[size=1em]    virtual void func1() = 0;$ x% i# B: S1 ~( u( ]
[size=1em]}* X2 }' K+ o6 D

! _4 o0 I+ |, |" y8 Z5 f[size=1em]class
2 m: s& T: {9 ]( f[size=1em]    InterfaceU23 O( x) F, L. A( p% k. Z3 p
[size=1em]{8 m: [+ O* q& e% J9 z$ F
[size=1em]public:
* c6 F3 H9 _: I% d[size=1em]    virtual void func2() = 0;
: r7 H$ K' h8 i0 w$ z[size=1em]}( X+ m5 x. P4 r3 V2 g

& s* |# n, @. N2 g, B6 j% _5 L6 o[size=1em]class
* J; z9 F; _& A8 @8 o& m" d[size=1em]    Wrapper
6 U1 ~, L) c+ a2 e) a[size=1em]{( h' [5 h9 t: T
[size=1em]public:$ ?2 x3 E; a+ H
[size=1em]    virtual InterfaceU1* getInterface1() = 0;# L. B  ~8 U% Z2 o. V/ ^' P
[size=1em]    virtual InterfaceU2* getInterface2() = 0;# E3 Y: [9 s) m% o% O) D7 D! B; W
[size=1em]}
5 R) }% [- i. z
1 J3 u+ K# L# l, j[size=1em]class  K0 R% R0 C9 r0 w
[size=1em]    Base : public Wrapper, public InterfaceU1, public InterfaceU2" m( f) j* y' ?
[size=1em]{8 y( T! k  r8 q4 V& A
[size=1em]public:
; r' y" D% q, Z  z[size=1em]    virtual InterfaceU1* getInterface1()
7 [4 F7 a+ f' N3 S6 \5 B  ?- w4 o[size=1em]    {
. b) C- Y4 y- y+ _[size=1em]        return this;2 G5 k0 G# z7 _$ {: a
[size=1em]    }
  E, Y; c. q( f, z[size=1em]    virtual InterfaceU2* getInterface2()
# \9 A9 Q2 i, z) A' Y* T[size=1em]    {6 X0 |7 B1 o5 @% T0 r) L
) A; F6 y% a! l/ r& b1 O
[size=1em]        return this;
9 O' L9 d7 v  H8 Q8 F' y& b( X0 r[size=1em]    }
( C( ^9 S! i( @7 m: D: \: M[size=1em]    virtual void func1()
, p0 @# h7 R% F[size=1em]    {
; c3 D4 J6 F6 d1 ~- d4 Z& \3 C[size=1em]        printf("%s", "func1");$ j! u  G6 I- v
[size=1em]    }
. @5 s" B/ V6 v* U7 _7 [# V
  k+ b3 \  J4 Y% E[size=1em]    virtual void func2()
& B0 G) Q0 v/ E[size=1em]    {. W2 ^* e! g% f: U/ L
[size=1em]        printf("%s", "func2");7 ~" E+ @" A8 [/ w( a$ S8 h
[size=1em]    }
" K: |9 `% R7 U5 m6 {+ F7 V; F9 u[size=1em]}
8 b2 k4 N, K. r: Z" g0 X1 G, y. u$ P- b' S/ I& W% G0 l* e

5 p* i4 c$ v# ~- K3 O
# T+ B3 i8 a: [' r* X9 |

( {. K. L# B9 F- H  @( O' g假设有如下代码:
: `4 o# H1 S9 L1 S% s[backcolor=white !important][size=1em]PHP code! \' G6 k3 T) H) y+ m, o2 f% L
[color=white !important][size=1em]?

# t& }8 i1 U$ {0 f* Q
[size=1em]1
" }- D6 g3 A( G, K2 n
[size=1em]2
( K7 h/ Y, c! _2 C" e' l# E
[size=1em][size=1em]Base* pBase = new Base();5 p% o8 g2 \' u& x: X: t
[size=1em]pBase->getInterface1()->func1();, D: R, Y2 n' n  \. _/ b3 q
7 R; P; g( a1 F7 d9 ^3 H
! k4 [' K  w8 ?  M
# c  Y7 |% i) G; \4 E

% q' N+ I0 y/ s$ |! O其实以上代码等于:& r! u' a7 J; u' u, ]
[backcolor=white !important][size=1em]PHP code; {  ^& u- N  r1 c/ D8 J1 @& t1 ^( Z& Y
[color=white !important][size=1em]?

& z* i" s# ~2 I' Y
[size=1em]1
% R* V. N* T/ h0 A
[size=1em]2
% i, U( T9 t. o# ^, P- R
[size=1em]3

7 n+ u: E0 k0 M0 u1 l
[size=1em][size=1em]Base* pBase = new Base();5 P4 k( y; s8 @6 q& r5 ?: L
[size=1em]InterfaceU1* pInterface1 = pBase->getInterface1();
% {1 x+ ^, P! E! T' w& I[size=1em]pInterface1->func1();1 `; g1 V$ w4 A$ Z5 s' A1 P8 y- ?
9 V0 }) b: c- h3 a! K3 a: r

0 r' G+ Y) U$ O5 q8 K
% S5 F3 ~3 i- j9 `/ k
+ s2 T- c2 L: V& B
# {2 X2 I5 W' b: I
6 B1 p2 q0 C; m0 }% PC++编译后,Base类的虚函数表如下:: h+ ]1 [: @) o  q$ S8 C1 I
[backcolor=white !important][size=1em]PHP code
) }8 Y: Z  j# l# ^
[color=white !important][size=1em]?

+ P% E) I  F+ W* i$ _% a- ?
[size=1em]1
& O% t! l9 N, M. X9 x+ L" T
[size=1em]2
8 g/ I' |: q  c# @
[size=1em]3
7 s2 H4 ^9 U: ]: ?
[size=1em]4

0 f$ c* }6 e$ j% j' c
[size=1em][size=1em]  8 T% F7 O( \. `5 o& R" |
[size=1em]vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|! e4 w' q& j( N, B" L
[size=1em]vTable:InterfaceU1 |Base::func1()|
: B1 y; [! q) j[size=1em]vTable:InterfaceU2 |Base::func2()|
* O! C9 Y0 i* @  U& S. E; z0 |! z5 Y+ w/ c5 y

( u2 b, O2 V8 V) r9 H& ]0 {5 k: ?; x

9 ~2 ~( J3 a: n( s) N0 ^: |8 p% q+ ^+ {! u/ l' F8 y! ~' t  \
如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。% C7 p; i1 S% z- \
但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。0 S; @( _( _( u! F2 I. q: K
C++是如何得到当前应该使用vptr[??]位置的函数地址呢?6 X$ z* }1 b/ ~3 n9 S& G8 ?
C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)
+ e( ?' L; s; c& b$ T4 C& c0 S1 n9 g) s2 J& b6 j





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