QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1631|回复: 0
打印 上一主题 下一主题

C++ 中多继承情况下 如何确定某个类型的方法,在虚函数表中的位置?

[复制链接]
字体大小: 正常 放大
蕾欧娜        

19

主题

9

听众

25

积分

升级  21.05%

  • TA的每日心情
    郁闷
    2015-4-14 11:21
  • 签到天数: 1 天

    [LV.1]初来乍到

    自我介绍
    德玛西亚
    跳转到指定楼层
    1#
    发表于 2015-4-17 09:51 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    [backcolor=white !important][size=1em]
    [size=1em][size=1em]  class
    1 }/ h; A" d6 W% ?+ h; s5 Y7 P3 i[size=1em]      InterfaceU1
    7 G4 X* W. K- f) Q9 J# a[size=1em]  {
    : i/ S5 ~% e/ E0 C7 L/ z+ r& n) }! R[size=1em]  public:
    * D, g4 J5 M* Y1 Q1 b, u" q[size=1em]      virtual void func1() = 0;
    & D1 D7 ]  J# r' ?) Q! e[size=1em]  }
    " i1 x7 j, t) L# q+ M
    ' g3 b( `: F) N9 X[size=1em]  class
    - `# U+ x1 g/ q[size=1em]      InterfaceU2- p* o- P3 D% H8 A/ Z2 N6 K
    [size=1em]  {4 N# y6 Z$ O5 a7 l
    [size=1em]  public:3 a+ t8 Z. J) `. ]0 Z& e
    [size=1em]      virtual void func2() = 0;5 l, M% u) T6 g9 v3 @: I" `! R  a
    [size=1em]  }4 N; \, ~7 w5 V* @' Y7 K

    9 @: p' r  G" Z, f' U& s9 X[size=1em]  class
    5 P3 V) I9 Y  H7 Z9 O4 x[size=1em]    Wrapper
    ; x3 O, M' G* x# t[size=1em]  {
    + X! o9 r2 Y; U9 ^[size=1em]  public:
    9 E3 Z/ m8 Q) S! t& p" Y" v7 o[size=1em]      virtual InterfaceU1* getInterface1() = 0;2 S( \& M3 G4 D
    [size=1em]      virtual InterfaceU2* getInterface2() = 0;
    9 l- l0 P2 f6 A7 Z8 ?0 {4 _[size=1em]  }' ]5 F3 [  `0 {) I% e
    8 o! s8 ?+ [2 X6 @' X5 `" C1 h% p  a
    [size=1em]  class
    7 W# G' U; c+ W* S! W# X[size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU27 n6 Z- n. b% G& B5 i) v3 |! b: i
    [size=1em]  {
    $ `1 O+ L2 X# e% U' c" x[size=1em]  public:
    - z% C% o0 H2 `( b) `6 k/ }[size=1em]      virtual InterfaceU1* getInterface1()* X! D' y( N. R0 L: [
    [size=1em]      {
    ' Q) B5 d4 ]* E7 z3 f6 W% [+ K) {[size=1em]          return this;9 b; {( X1 X8 C! @& y# B  j
    [size=1em]      }
    5 T# J0 w+ C/ W. J[size=1em]      virtual InterfaceU2* getInterface2()
    ! \1 V/ z( I: A, r- P[size=1em]      {( T  `  a9 K: |' |4 L; L/ |
    7 \( C0 C! P( h
    [size=1em]          return this;
    3 L1 k* Q5 C6 C/ q[size=1em]     }& ~: t* h0 @. t7 T# X) v
    [size=1em]     virtual void func1()0 P& l, N* }( b- W
    [size=1em]     {. U+ `# m) A( l  Y; ]1 l7 e! o
    [size=1em]         printf("%s", "func1");
    ' x" T4 @1 u# h: L7 J$ T2 ][size=1em]     }( L& i0 H  e& H" `, E2 ^
    % H' W9 H, i" J4 {2 ~% Z
    [size=1em]     virtual void func2()
    2 M/ d4 U/ P% ?0 J[size=1em]     {
    $ K' _$ }" H. r& C7 U[size=1em]        printf("%s", "func2");' W8 G% @; b3 r# N6 V5 B# H
    [size=1em]     }7 d; [7 }' N5 E$ g8 [( S! q
    [size=1em] }
    : n  _3 z7 {# Q3 k6 T: f' F- h: q$ V: H# e2 N/ G  p
    9 I. I4 S! i0 |+ i% \: K2 z9 r8 B

    - E9 Y3 I# B: v4 M1 O# n  _$ D3 b4 p) e
    假设有如下代码:
    / K% W( f* r" t1 m5 W[backcolor=white !important][size=1em]PHP code
    + D$ @: w2 G. M; a
    [color=white !important][size=1em]?
    ; l) \0 ~. k/ u1 v& d2 j: I' b( M; e
    [size=1em]1
    9 y8 j- `0 a8 ^) M2 D! O
    [size=1em]2
    & L: z/ G! \& @. s. j
    [size=1em][size=1em]Base* pBase = new Base();
    ; @. U' r( _$ E, ], W[size=1em]pBase->getInterface1()->func1();$ }$ G/ Q1 [1 u" d+ |# m$ q8 q
    9 v- O  Z; L  F* \5 `
    1 b" @, @$ U. t( `: [

    2 K. y  M* N9 c0 G( h  v1 l& l! Z% H9 Y
    其实以上代码等于:
    % R& O7 i( z: J  z& U2 `[backcolor=white !important][size=1em]PHP code7 A( \' z: S. F1 \# j1 r& k& z
    [color=white !important][size=1em]?
    ! ~5 O6 ?& f( U2 h
    [size=1em]1
    ' y$ A" b$ ]3 |* D& ?4 b% j1 r9 D+ L
    [size=1em]2

    . I* \4 L7 S5 I% v  s
    [size=1em]3

    4 w2 b; V% r4 Y
    [size=1em][size=1em] Base* pBase = new Base();
    * B6 C" g, T, P, [- e9 z  T4 c: f[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();1 P$ e4 _) c# I
    [size=1em] pInterface1->func1();  N5 K! @. _, @0 y" P3 `$ L+ a4 ?
    8 x! B& x3 Y+ Y! R" ^+ n. V6 C# _
    - X4 D( ^0 p/ V$ q

    * Z& N6 `( b, B  f: b- e2 |* v8 h8 l& |: v* O
    * x$ r& n, m8 p

    5 ]' H& x% Q+ X  p/ X              C++编译后,Base类的虚函数表如下:
    ) a) Y' a& v% h& ?* Y2 @( m" C[backcolor=white !important][size=1em]         PHP code/ C! U  P# E/ B" X- J
    [color=white !important][size=1em]?

    ; e% V; W7 E; M1 i1 K
    [size=1em]1

    , Q2 n7 {9 p3 ^& d0 I
    [size=1em]2
    ; q% B8 q; W. E7 C* M" l% A
    [size=1em]3
    ; ?& z0 u% I0 z2 D0 G5 X5 ?1 [
    [size=1em]4

    1 O! H1 P# j. {/ V" v, ?
    [size=1em][size=1em]  
    2 w  U; }5 A3 |  A& Q8 J[size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|2 Q' W* e$ o0 o# m0 a$ c3 ~, Q
    [size=1em]  vTable:InterfaceU1 |Base::func1()|$ \; J$ i/ u* T1 `
    [size=1em]  vTable:InterfaceU2 |Base::func2()|
    + U* z6 C4 c/ P( k* s
    & z0 p; V" D- D9 V" T2 {

    3 e$ O: @" ?# \' x5 j
    - o" H6 R4 W# c( {' t; k" m% T% J6 ^( l/ r% T/ }
    1 K; k" V! ^/ |8 J+ D; X
         如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。9 ^1 I! Y; c! H( p; z  F
        但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。, h9 k, o9 T$ l) T% c; L7 `
        C++是如何得到当前应该使用vptr[??]位置的函数地址呢?
    7 T/ Z0 h% Z: {/ N' l& r0 u    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)+ o% l0 I# k  }, I' t4 d
    + C# K1 w' z7 ]( i0 g) h) a2 \8 p0 W6 w
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-4-13 13:11 , Processed in 0.341649 second(s), 50 queries .

    回顶部