QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1621|回复: 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
    % t' b* X  w7 K& q+ a0 ?2 q[size=1em]      InterfaceU19 R( `3 X8 J: n  R
    [size=1em]  {
    ( N0 M3 S( V6 Y% ?[size=1em]  public:
    / t" m5 h! y6 p! S[size=1em]      virtual void func1() = 0;
    - `) \# B7 J# s# V6 o9 I; O[size=1em]  }
    & _5 ]7 T! Y/ D; C3 N+ i7 d& c/ W. V8 K$ e/ E1 E
    [size=1em]  class' f% ^9 ?# [  x  ]8 h
    [size=1em]      InterfaceU2' u7 M5 Y* v5 O2 \' v: c6 {& W. e; l  J
    [size=1em]  {
    8 ~5 e/ g( V) E5 l7 f8 H[size=1em]  public:  x% r: V. ?( y6 X# t( D
    [size=1em]      virtual void func2() = 0;% B. m! ^% A' C& ]/ g
    [size=1em]  }* e9 P( c# Q# f3 ]4 q, Y  p
    1 p" @+ ^! P3 |; B9 H
    [size=1em]  class
    0 h/ ?, j( f9 X! I  X1 E$ q+ B: b[size=1em]    Wrapper2 r2 W$ A# ^* V- `4 n$ e# {
    [size=1em]  {
    & B+ |0 e4 C/ U% F4 [" L[size=1em]  public:* y/ U9 @3 q1 ^. _% s% I  P1 P
    [size=1em]      virtual InterfaceU1* getInterface1() = 0;( u* X& U  Q" l1 a& F3 i! K! i7 o3 `
    [size=1em]      virtual InterfaceU2* getInterface2() = 0;; L6 s  c  B4 b% h* T. K
    [size=1em]  }
    2 m7 j8 Y2 S9 ]3 y' o# T9 T, ]" R$ S. w% ~4 H- E" }- |, F4 g
    [size=1em]  class
    , p2 F6 L: j6 D/ f& s[size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2
    6 K; v# k2 y( P9 J: r# F  w+ R- _[size=1em]  {6 b- X$ Z; T8 ^" Z3 V. z% K$ Q
    [size=1em]  public:
    7 h4 m, X# g7 A3 h- e[size=1em]      virtual InterfaceU1* getInterface1()" v- t6 G- e0 S& H
    [size=1em]      {  D9 y" d/ Q# J4 L& v
    [size=1em]          return this;
    $ A' k; [5 i+ l3 ?3 K[size=1em]      }: q2 g9 G; M) N* a
    [size=1em]      virtual InterfaceU2* getInterface2()
    . P$ b1 v9 \& ]: C[size=1em]      {
    ' u2 o$ M$ l7 J  {8 e! l8 v+ z3 M2 v& j1 G6 E
    [size=1em]          return this;
    % d9 y9 H9 H1 L' R  P$ J0 ?[size=1em]     }
    ( _% G  H6 y7 V2 P8 m" t' z[size=1em]     virtual void func1()+ F/ R. l( r* K  N
    [size=1em]     {1 o. l- s: z* n+ N+ o
    [size=1em]         printf("%s", "func1");2 _4 {3 Q! \# t; l# o; M" z
    [size=1em]     }6 p+ Q8 j; d6 Y$ i. B- U% s
    2 `6 \+ u$ ^8 z! V# ~5 t' a6 l
    [size=1em]     virtual void func2()
    8 d1 ~1 x9 x1 G* e[size=1em]     {
    ' [' B6 m% T" z, b9 G[size=1em]        printf("%s", "func2");0 {' l2 V+ @* E7 n4 d* `* `
    [size=1em]     }+ o% V  l+ s, ^9 \) @5 T/ k, ~2 z
    [size=1em] }
    6 F, H% S1 F) t8 n# e  W$ r9 l; W4 Q, Q. {

    + B( g" E3 u1 O, E8 }6 @6 J
    ! q5 h2 S4 T5 Y1 x' D; [
    + c1 ?. B7 G! j3 a& U
    假设有如下代码:
    + U: ~" g+ G: |- }' S# O2 n% w[backcolor=white !important][size=1em]PHP code
    " F- R, D8 j2 H8 l& n3 E
    [color=white !important][size=1em]?

    0 L* J# P- S! V6 X+ r7 o
    [size=1em]1
    4 t4 O8 b7 r. r- {6 T0 c
    [size=1em]2

    % N0 B5 t2 i4 d/ W" H6 W; }
    [size=1em][size=1em]Base* pBase = new Base();
    8 t# o: j' l" ?- F0 I! J[size=1em]pBase->getInterface1()->func1();+ B5 Z5 r0 s, K. H+ M' L
    ' \. D2 u* j0 D+ o6 p, O

    8 E. V9 a; M7 K* S& c
    ( \4 g* |3 u1 k
    ' d4 w$ C! V8 y* v" \4 A$ e8 b其实以上代码等于:; h' _* W8 z  X, S6 M
    [backcolor=white !important][size=1em]PHP code
    * W. }7 ~2 q, D9 U4 X4 Q
    [color=white !important][size=1em]?
    . x' C! ]+ t( y( C( [
    [size=1em]1

    * P9 J' ?# z, i4 p
    [size=1em]2
    6 }; A3 C3 M) Y$ u+ l
    [size=1em]3

    7 s. S7 v$ W, O' u6 \
    [size=1em][size=1em] Base* pBase = new Base();: [" d; \6 y9 l0 c2 ?8 M
    [size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();
    4 ?; L/ `) c) A+ e; K[size=1em] pInterface1->func1();% z0 ?8 [  `/ F3 P/ w9 H, P
    0 {; }  U4 K% d. p0 s9 w
    6 h/ n% t9 {6 k" Y
    " d! Y% W8 g. a2 z3 t
      {! Y9 L7 Y* F

    3 r3 m% l  `* P4 z8 v( \4 O5 ^0 @
                  C++编译后,Base类的虚函数表如下:
    5 N# ~# _5 h2 [& j4 j- B# G[backcolor=white !important][size=1em]         PHP code; Q7 z% S) ]1 l+ Y
    [color=white !important][size=1em]?

      ~) R8 Y  v/ J: z8 Z% r: \0 N
    [size=1em]1

    ( [, f5 ]8 v- l( f2 [& s
    [size=1em]2
    ) S3 Z2 `" w8 I: C5 f
    [size=1em]3

    . y$ g5 Z5 w2 g5 X, {+ P
    [size=1em]4

    ) E1 Y+ Q! }4 Y3 j3 P$ ]
    [size=1em][size=1em]  
    0 D# O$ K* y# r2 C0 d1 E) ?5 E[size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|
    ! p" D" O0 z6 n; W* _& \% z[size=1em]  vTable:InterfaceU1 |Base::func1()|# V- [, y# O& }+ j9 D% J
    [size=1em]  vTable:InterfaceU2 |Base::func2()|, T" E' u7 [6 K4 g: G: o4 b: W, j
    * [$ X3 J! ~/ C- J; N  V; P

    8 l2 w5 d0 j0 ?, q4 L3 U& R, x+ c/ a! i

    ; v4 e) u/ X6 k% G0 S7 F, v2 x+ |# g2 Z; R  P
         如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。
    ) x7 u5 q' ?: F1 c# s    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。
    6 ^" w" C6 R" N/ `1 D2 [    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?- a" v9 |" k4 ?9 ^
        C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)
    * E" C9 b" @5 B! Z; S3 o9 Z- l8 N3 T, }* }9 c8 Q6 v
    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-11 00:30 , Processed in 0.412927 second(s), 50 queries .

    回顶部