数学建模社区-数学中国

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

作者: 蕾欧娜    时间: 2015-4-17 09:47
标题: C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?
[backcolor=white !important][size=1em]
[size=1em][size=1em]class
* H& I1 Y5 A7 D+ @; {/ H3 v) E- E[size=1em]    InterfaceU19 i) X) Y$ V' [) H" C7 b, O
[size=1em]{
5 U6 i+ T& @+ V; z1 s4 C8 u[size=1em]public:
" [# R$ R( v+ R0 v% P) Y[size=1em]    virtual void func1() = 0;
* i' S) e+ n! L4 `( z% F: H9 G0 x[size=1em]}& R/ @" U& R8 }+ U+ {

7 I- p. o: l% r[size=1em]class
9 Q6 A- l9 f4 }) W[size=1em]    InterfaceU2
% N/ U/ ]  l" k5 ^& a[size=1em]{( I& C: W: b0 q5 J( \- v6 p
[size=1em]public:
# }# o9 X# L1 p! n[size=1em]    virtual void func2() = 0;  w: L- \) H' D7 k! c( B( V+ d& _
[size=1em]}6 A- W. `! F' C7 H
, t; x( g9 O1 q, T
[size=1em]class
5 X4 D2 M* g2 B& A8 d0 F[size=1em]    Wrapper5 Q3 ?# O- b7 I5 m/ f0 v4 E
[size=1em]{$ q5 o: F6 v4 m0 \- _& E- }8 o0 P
[size=1em]public:
& F( g  p7 B: B[size=1em]    virtual InterfaceU1* getInterface1() = 0;
* f( `8 q2 x! m4 Z6 U# b# s* h[size=1em]    virtual InterfaceU2* getInterface2() = 0;. d- t" {! [, k  M
[size=1em]}
* f# b5 G- K; a- w( G/ h0 i
: T  T% G, j6 B6 u# |[size=1em]class" t& H" r7 n9 y3 K/ G$ L0 I
[size=1em]    Base : public Wrapper, public InterfaceU1, public InterfaceU2
$ n0 i# i, w. P+ s+ m[size=1em]{* u9 \! P! B6 S
[size=1em]public:
* f8 n; ?/ g" \" v( F7 a& Y0 j+ l. |[size=1em]    virtual InterfaceU1* getInterface1()9 W5 s( v! V1 ]
[size=1em]    {- L1 K2 n- o4 k6 B2 c$ U
[size=1em]        return this;% U5 D  v7 @8 p& ~! ?; v
[size=1em]    }2 h, l$ b! F. ^% D- o* k; g
[size=1em]    virtual InterfaceU2* getInterface2(); a  E/ {$ E0 k8 F
[size=1em]    {8 g/ q6 ~; p0 c4 D! N- {
: \; j0 h/ b, h% D
[size=1em]        return this;& c) b8 s7 J+ d5 u3 ]
[size=1em]    }$ e6 X! Q7 I" O$ _2 I
[size=1em]    virtual void func1()8 Z; O9 m. p" I: u1 Q
[size=1em]    {
, V( }) u( C, l1 C: [2 y4 ?* r$ y: {[size=1em]        printf("%s", "func1");
5 D( Z1 f, b6 e4 C  A[size=1em]    }. y2 O1 q' {* O# F$ c8 {, E

4 W0 [# b9 |0 x3 A7 p% I( O4 G[size=1em]    virtual void func2()3 `: S/ w' ]( o3 O! Q/ X3 U: q, F
[size=1em]    {
) r, J1 V7 h! i[size=1em]        printf("%s", "func2");
) _& W8 P1 S) v1 w, f0 `[size=1em]    }! k' Z8 Q* a0 y/ H8 y& X. K. t
[size=1em]}
2 K  s: U+ A  W6 e+ Q: i
) o1 ^: a' U* c/ M! z( Z2 a# W

2 w; |2 `' s# d+ U

% |5 H! p. b, z8 @
' t( b5 F' e! M) K& B- ?/ ^& H3 z假设有如下代码:
5 v, ]2 {, G6 W# n6 r5 [[backcolor=white !important][size=1em]PHP code9 m, V, ?" `0 O. Y3 a0 E* k$ a, _0 o
[color=white !important][size=1em]?
5 a/ p# M0 r5 Y8 D  }( ?
[size=1em]1

3 _# w; ~: C1 m2 U3 k
[size=1em]2

$ |3 {- B& e# N4 l+ x
[size=1em][size=1em]Base* pBase = new Base();
) ?: q/ r* W/ S: }4 }+ _[size=1em]pBase->getInterface1()->func1();' C* Q7 a: \# O, B0 F* `9 R3 A
. h+ a5 F! ~) N6 J2 r

6 G' C2 n" Y. k% W0 F, U  G) u# Z! `6 n- B
2 }4 u( x5 f$ i5 a( T: @4 {
其实以上代码等于:, H4 e# C3 w9 L. j/ V( x* n0 s
[backcolor=white !important][size=1em]PHP code  j+ N1 U8 [7 o  f8 ^$ a) R
[color=white !important][size=1em]?
2 C5 q) w  h6 o" H# S- ]3 |
[size=1em]1
0 x* p6 U5 V" \( V
[size=1em]2
' o+ C9 a  H/ `% e- ~  a! S
[size=1em]3

0 d4 I; t. e+ d' n; H5 ]
[size=1em][size=1em]Base* pBase = new Base();
* x8 i$ J* {; D6 ^) {: y[size=1em]InterfaceU1* pInterface1 = pBase->getInterface1();
/ K; d( ~: ~) N" L; M- d[size=1em]pInterface1->func1();: K# C+ [( k/ i
, h. I/ p6 X1 l
3 c2 Y- V5 ?0 W6 E3 D

$ T8 ^; E( m( O( t8 }( v$ ]: T& q
, o2 _+ X9 o/ q6 P3 Y. H* `

) d& X1 U' X9 q* d* VC++编译后,Base类的虚函数表如下:
" x) O& [2 B* ^1 A[backcolor=white !important][size=1em]PHP code0 i( P- t( j" q' ?) A
[color=white !important][size=1em]?

3 w' T* w  w  d5 q+ w
[size=1em]1

' u! p! p! w9 A, t6 o; }& ^/ q
[size=1em]2

! R' P7 m: ^' ?, V% @# H( E
[size=1em]3
: R0 l( W" `8 C5 Q0 \# v+ G
[size=1em]4
6 z. ~* V: Y& R9 Y/ g1 D7 w' ^
[size=1em][size=1em]  ) U+ ]# v" u0 c! C0 h) _
[size=1em]vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|1 v$ L' G: y" u2 s7 L: s
[size=1em]vTable:InterfaceU1 |Base::func1()|9 O! z& l/ M- V1 U
[size=1em]vTable:InterfaceU2 |Base::func2()|9 [2 e8 y# O3 {: G

) q. M. }* k# H3 x
" a. x4 F0 g: r. u! ^+ ^; ?

- ^" {+ ]9 C3 Y- _7 {
; l0 T7 C# t2 V- u4 P5 A- l3 {
- v# `, z& f' n4 ]如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。
* U! S$ c! Z* d" O* ~: g  H/ m但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。& h3 z3 ~/ g+ ]; s* t9 W
C++是如何得到当前应该使用vptr[??]位置的函数地址呢?1 }( o6 d% }8 i5 s) ]: O
C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)
0 i+ V6 \4 j  y0 {3 h7 Y( U3 _
9 m  [- B. T) N' ]4 ]; A$ ]& N




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