QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1675|回复: 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
    ! X1 e9 u3 }/ K5 \, I) o" v[size=1em]      InterfaceU1
    / n, R( A% b, [1 i[size=1em]  {
    & r8 e* o; u* l5 U! l0 B. E[size=1em]  public:
    0 j4 f2 v- {; d' I% |% a[size=1em]      virtual void func1() = 0;
    3 ~8 H. F' u# N+ B" D, K[size=1em]  }
    6 I& s7 s2 d" l8 v& a( |! {7 `! p4 u" [$ r  G# x/ h
    [size=1em]  class1 _* N6 H1 z" H9 L' w) [
    [size=1em]      InterfaceU2
    & ^; ^; W  y6 R+ _$ e& Q% ^" R7 R[size=1em]  {
    $ p- s( I7 I2 L# t& x3 x9 ~# c[size=1em]  public:
    % C7 B9 k. Z  |0 [1 I& _& v& d4 a[size=1em]      virtual void func2() = 0;
    ' T9 ^" Z2 F+ i/ \* i" L[size=1em]  }
    4 \- q& t$ z" D1 T( C8 d
    ) g; a2 u8 X$ Z5 B  q  b/ q[size=1em]  class
    ' M6 ?3 W1 a$ P2 ^6 c" C1 c# w[size=1em]    Wrapper( y; U0 P& W1 E; H) {# ^
    [size=1em]  {( b2 `/ L) m2 ^/ V  m
    [size=1em]  public:
    ; k5 Q7 k  A! \' l" e# l4 q[size=1em]      virtual InterfaceU1* getInterface1() = 0;# Y) w. w0 y1 K* _: o
    [size=1em]      virtual InterfaceU2* getInterface2() = 0;
    ) F9 ?5 s5 Y, }6 f[size=1em]  }5 }1 x5 f. `# {

    1 H( O/ S& x% X) r[size=1em]  class
      F9 j0 [4 Y- N5 X" D7 }[size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2" M2 j) I1 |, i/ d
    [size=1em]  {* _6 ?! R1 X" r) f2 z; l5 x3 A$ d  \! z
    [size=1em]  public:
    ; q) {8 D$ M; C3 k+ T. T[size=1em]      virtual InterfaceU1* getInterface1()
    & k+ P. A: x+ b$ H4 y4 o/ Q[size=1em]      {/ c' S! i2 X) q5 T7 U9 H6 S
    [size=1em]          return this;
    8 O/ d. J' {" Z, Q[size=1em]      }7 a+ D4 a  y3 A5 I! K1 @& {
    [size=1em]      virtual InterfaceU2* getInterface2()
      |" y/ r) w1 L' T6 b' R( n9 v[size=1em]      {
    3 O+ e; A9 U/ \1 o" w* S3 |- t
    : g; a1 ~& I, L7 X$ P6 B0 X& t4 s[size=1em]          return this;
    4 ]! b7 s+ y1 Y$ a$ p4 ?. R4 F[size=1em]     }  ?  y8 j3 z: h# f3 i9 X. C! [
    [size=1em]     virtual void func1()% n: S. {, j! \* t- E' }6 `: w
    [size=1em]     {
    / y7 T4 H3 R7 D[size=1em]         printf("%s", "func1");; ?; {1 V! m/ f  t
    [size=1em]     }- Y% z  x- I! |! U2 j# e4 I: z  ^$ x

    % \8 d1 k2 {/ w- o8 T, Z[size=1em]     virtual void func2(). h- x1 j! `7 P7 I
    [size=1em]     {: Z# O& Z; f5 B# e% S8 |2 }  V; A
    [size=1em]        printf("%s", "func2");! l2 g8 X2 c0 A( m6 T8 G6 F
    [size=1em]     }
    + p. `: h3 F+ [8 J% d% z* P/ ^[size=1em] }/ `% ?: O7 p# W/ ^
    3 }: C) s7 t! P0 X' ?

    / I4 U/ o5 ^1 m" P, u; {3 @
    ) ^8 T* R, M! m  N7 `
    ; i) E6 J+ h9 e+ p
    假设有如下代码:
    & m0 o- b& R, n8 J) h* }; K[backcolor=white !important][size=1em]PHP code
    : @( A" p+ r. r
    [color=white !important][size=1em]?
    , a- Q$ B# K/ N5 d3 |0 U' G0 q
    [size=1em]1

    1 T7 `! l/ x6 n6 X9 s
    [size=1em]2

    $ |+ ]* V1 M3 c5 q0 H9 [" o
    [size=1em][size=1em]Base* pBase = new Base();
      S+ P, C) Z4 p% G4 `$ a: ?[size=1em]pBase->getInterface1()->func1();
    " C+ F9 s+ q; P9 Y* B4 B+ ~9 u  _! h. \

    ) O, B" y0 o( G1 O6 z' _- I: {' t* X8 W
    ( P8 _7 L2 a' a* x
    其实以上代码等于:
    6 ~  o& C7 y( j! {. t- K[backcolor=white !important][size=1em]PHP code
    7 a. d6 `! c4 {8 W3 ?( I6 {1 C
    [color=white !important][size=1em]?

    1 M7 I/ J! R1 U/ a: V
    [size=1em]1
    6 N1 A. f; m( N
    [size=1em]2
    3 c. v6 _' d) \- {6 l+ i
    [size=1em]3
    - F  C( u/ a$ l/ p* \
    [size=1em][size=1em] Base* pBase = new Base();
      T! B9 D6 A; a# C( r1 ]) v[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();
    * a; A. A5 X# M+ e4 I9 D[size=1em] pInterface1->func1();' ?5 M, g- c$ f
    ) ~* e. ^0 Q" M- u% M

    # c' Y0 H* \3 A  f  o9 V9 \4 m; N$ I( a  Q+ ^* G9 y

    ; W. d. ^3 x. S3 L5 Z4 b
    4 n  E, I$ ^* e% l" D% @
    " ^* l* h' M, H7 e              C++编译后,Base类的虚函数表如下:9 H$ _. ]6 R  V. T/ Y
    [backcolor=white !important][size=1em]         PHP code- W/ p/ |9 `+ y- l: c
    [color=white !important][size=1em]?
    ; v0 \; E! N: i' e. j/ z$ q
    [size=1em]1
    ; P4 k! J& n4 h+ e6 ?" X1 O& H
    [size=1em]2
    + p( D6 Y( d4 j. |4 i: G7 M; _4 j
    [size=1em]3
    , o# k. L1 K* t# {! L6 X- B
    [size=1em]4
      }* r8 ]) n# b% S5 ~
    [size=1em][size=1em]  ' S- A9 t5 a% G7 C! ~3 w
    [size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|
    % O' A0 V6 I# j- k5 r: u) A[size=1em]  vTable:InterfaceU1 |Base::func1()|
    ) H. P! T/ w* h' j- e' O[size=1em]  vTable:InterfaceU2 |Base::func2()|
    ' U  V# h4 P3 u
    9 W- a* E+ s1 V  \( k
    ; c' _7 e, q( s- u+ f7 `9 a
    ( H2 H8 n8 q3 w* Y- ]  n9 ]

    - A0 N1 ?8 L! ^/ ~1 A1 y3 x6 w) C, O2 X2 t9 Q
         如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。. Q0 u  a4 N' `
        但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。
    7 q# M* p9 @2 K8 [    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?" c9 \# a0 A; `$ ^  z- z9 X! s7 W% ?
        C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)  A, L% z0 Y4 m
    9 T. w9 Z- t3 `; c# A
    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-6-19 12:34 , Processed in 0.413911 second(s), 49 queries .

    回顶部