QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1634|回复: 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  J& F2 ?" D7 n- \; T( C. ]0 Q
    [size=1em]      InterfaceU1
    2 S9 ]5 z" X4 Y* E! {% @[size=1em]  {
    $ g7 s0 A5 ?2 T7 t/ x[size=1em]  public:
    + ]3 y% t% w, w, y7 N! C* W[size=1em]      virtual void func1() = 0;
    6 t. Q# x# {# M[size=1em]  }
    $ l+ v3 V2 l% k. L
    ' X- R: y: _' @8 `1 h2 C[size=1em]  class
    3 a: v! n2 [4 |/ v, e0 k" D[size=1em]      InterfaceU23 N: c/ [1 K, w0 ]( n3 G' ~
    [size=1em]  {+ g+ M1 \& t& H& n: N# L
    [size=1em]  public:
    2 O& m2 X, R# Q4 b[size=1em]      virtual void func2() = 0;
    $ u1 m9 ?% o( ?5 m+ g[size=1em]  }
    / `5 V& x3 [4 x' o6 c) ]- d+ j) G1 P' o- B
    [size=1em]  class( P+ q% s# R- ?8 A: d' j$ n- l2 J
    [size=1em]    Wrapper. x  Z1 F2 e+ C/ \0 p( g( S0 ^* H) o
    [size=1em]  {1 i& W+ Y& x' y: P
    [size=1em]  public:
    * w7 g+ ]9 P  p/ s[size=1em]      virtual InterfaceU1* getInterface1() = 0;( X  |) y" d/ ]5 P- N
    [size=1em]      virtual InterfaceU2* getInterface2() = 0;: K, C2 }3 ^5 @! j9 q& A3 s1 Z
    [size=1em]  }
    " e$ X0 L/ S1 ]. ]% V: V! \4 g! x3 i' c6 V! n, ^% C* L# [
    [size=1em]  class* b! `# z0 ~( `* X- h% a, }
    [size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2% n3 f+ Y! W( J. e% O
    [size=1em]  {9 N3 A& G' @! N7 P2 T+ B0 n  z! i, ^
    [size=1em]  public:. {# C5 A3 Q& n
    [size=1em]      virtual InterfaceU1* getInterface1()/ {/ g$ [5 ~6 U
    [size=1em]      {; Q( X# Q- F6 m% d. @0 J! @
    [size=1em]          return this;. C/ b, c& \# a- Q* C* O
    [size=1em]      }
    ; T6 y/ C6 r, f3 W  k7 q[size=1em]      virtual InterfaceU2* getInterface2()
    : R# c: J: u/ Z; Q[size=1em]      {8 R) ], J9 Y$ ]: G7 S

    - ?& f( ]# W: T+ O  N" C" ]/ Y5 D[size=1em]          return this;
    6 A1 ?2 u4 M4 ^! f0 m& |) o! t[size=1em]     }& N. X9 I* |( [+ F' Q9 A5 Z# \3 D
    [size=1em]     virtual void func1()# E% r0 b' J4 w* `* u' i! L7 ~
    [size=1em]     {
    , ~4 p! D5 C" b) n, Y[size=1em]         printf("%s", "func1");
    3 \, B/ c: j% _+ Q$ L4 V* D[size=1em]     }
    , ~9 z9 Q7 p+ ^8 y1 W$ ^% I! K( o0 W! Q: f3 V" h, W, J
    [size=1em]     virtual void func2()2 f. d, t, \( L" t/ t
    [size=1em]     {
    " P% g, K  x" [[size=1em]        printf("%s", "func2");
    + e6 s; d7 v% S; M( q. o[size=1em]     }
    * [. @0 f. G  i  r, o2 M6 _5 {) O[size=1em] }
    $ L9 H- T, C( R/ r, e, |6 u- c8 U2 r( w/ J/ b
    & C. u  ]  D2 Q, Q3 y. H8 n
    + y' P7 m( ~- ^/ c6 F) _
    6 h' ?! m& x) Y& v9 h) A
    假设有如下代码:
    % _4 e) Y' S1 B. E6 @" T) Y[backcolor=white !important][size=1em]PHP code- I* C" \. k( D5 E
    [color=white !important][size=1em]?

    , Y7 c1 {3 K8 z% h3 e8 J" U5 }( E
    [size=1em]1
    ! d  a( Z( x% x* h
    [size=1em]2
    , n7 w5 e( {/ T& {- I7 `2 I1 n
    [size=1em][size=1em]Base* pBase = new Base();
    / C( @% w/ B# a; a, ^6 f7 G[size=1em]pBase->getInterface1()->func1();
    + o$ n# r* Q# e& b- d( H4 _% H! @9 Q, S, x& K/ [
    7 Q4 r2 d/ Y! V$ {

    6 R3 [! B9 P9 f9 B0 ^% }) N5 T0 A$ `) f
    其实以上代码等于:; a# e# S2 t8 `- B* p2 O: E! L& u$ f
    [backcolor=white !important][size=1em]PHP code
    % T; a8 r. t* `' t! k
    [color=white !important][size=1em]?

    : Z: s" y* H% w8 E, X# @, h! Z% I
    [size=1em]1

    7 H* ?+ {. ?2 T! w/ l+ o# y+ E
    [size=1em]2
    5 l4 B0 P3 g" ?" k9 h1 P
    [size=1em]3

    5 b+ g6 ]; ~' m& Z' [' b
    [size=1em][size=1em] Base* pBase = new Base();
      _  y7 T* i5 |% [# }[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();$ Y$ H4 L7 `" l) E2 _0 @9 L
    [size=1em] pInterface1->func1();. b; ?' ^- C2 s  v4 _) W# C( J
    # z) d4 I6 @4 X2 a6 D, u

    ! w. o0 }$ i- u5 \8 G2 N
    1 ?: K( _& h; X1 E- _& O- G
    : u* M. F) n$ t! M6 G" |* u9 ^: F8 [; }) }3 S( e" N
    ) f' \4 p% Y9 y& M, j2 y$ w
                  C++编译后,Base类的虚函数表如下:
    - l- Q' m+ }8 V) S3 T9 B[backcolor=white !important][size=1em]         PHP code
    + R7 |' v; q. w* H* B, Y1 l
    [color=white !important][size=1em]?

    8 ]) @* U' M' m2 ~9 U; _6 Z/ r
    [size=1em]1
    9 M; S' T2 k2 c3 i) K
    [size=1em]2
    + e; y: o* V  m9 C; q6 e1 ?& }4 h
    [size=1em]3

      E* O8 S) F2 \; k
    [size=1em]4

    - ?7 `" k, q; Y3 ^% W
    [size=1em][size=1em]  7 L2 B$ e  Q/ ]* f% G
    [size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|
    & }) ]3 B0 b% L6 `/ U3 V+ F' T" p[size=1em]  vTable:InterfaceU1 |Base::func1()|
    . R4 J+ e3 J5 S6 d[size=1em]  vTable:InterfaceU2 |Base::func2()|* e8 T3 c: S# C2 x+ f4 I8 O
    4 Y& J6 o6 T6 o5 o( w
    2 n/ l! j0 R( u1 k0 d
    3 a; ]. r2 o; [  o) K0 |) a5 A: n$ W
    ( T+ _( g. P: H$ o
    ( |+ v* T2 g2 |  L! ^+ U3 T
         如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。
    5 u2 `6 ^8 }8 ]' j/ b    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。) H! C% h" \6 [* v+ m: U
        C++是如何得到当前应该使用vptr[??]位置的函数地址呢?2 S' C1 E& b( |5 }9 T2 V
        C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)8 G9 m9 x/ f& g5 H1 _

    8 M8 f# U1 o. E
    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-16 09:55 , Processed in 0.413586 second(s), 49 queries .

    回顶部