QQ登录

只需要一步,快速开始

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

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

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

19

主题

9

听众

25

积分

升级  21.05%

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

    [LV.1]初来乍到

    自我介绍
    德玛西亚
    跳转到指定楼层
    1#
    发表于 2015-4-17 09:47 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    [backcolor=white !important][size=1em]
    [size=1em][size=1em]class
    / p; d0 h# m! Y$ H) W2 g6 F[size=1em]    InterfaceU1) p: P$ e) v, j) Y6 E9 ]
    [size=1em]{; Z/ [7 v$ U& G7 q; c9 e/ I( x3 r4 ]
    [size=1em]public:; g; e  ^1 {  C: T! a" d4 G7 x' n
    [size=1em]    virtual void func1() = 0;: F# V" \8 e0 S8 m8 y) Z! i
    [size=1em]}
    + y& v. L1 T0 R- O; c' s0 d7 {2 b( J
    0 L' u; \3 X4 n3 ^- Z[size=1em]class( \; o' s; ~% C+ p
    [size=1em]    InterfaceU2) e2 W) u* g% D: L& }
    [size=1em]{, a; d& n4 P- i
    [size=1em]public:
    " e0 t: z# |$ J0 M  j5 w[size=1em]    virtual void func2() = 0;6 X' D' e* ~+ [" U2 I  T
    [size=1em]}
    ! h. O2 i, Q" F0 p1 d/ F1 x5 s) Y! i5 \! B! J. U
    [size=1em]class
    5 u4 J& c# h! S* A" E[size=1em]    Wrapper4 M* |. \) t5 O1 p5 e5 g% k
    [size=1em]{  J; O6 w- G( j( W
    [size=1em]public:
    . N6 Y* C; U5 H+ J! U8 a( E  X[size=1em]    virtual InterfaceU1* getInterface1() = 0;
    & g. [  V8 Z1 b3 Y$ I* v5 B- P* R[size=1em]    virtual InterfaceU2* getInterface2() = 0;5 s9 U: D. |8 x/ F7 d
    [size=1em]}
    0 s( _, j+ F7 e- o, w8 w9 W
    ' F. U) @& t7 q( h3 R: `1 b[size=1em]class0 j6 ^1 I8 D- p2 c9 Q3 D9 x0 Y
    [size=1em]    Base : public Wrapper, public InterfaceU1, public InterfaceU27 Y# ^/ M/ b* @" R0 U/ i6 |6 d/ b
    [size=1em]{  C" U! d3 f" Z' H% s9 }
    [size=1em]public:
    2 b" f3 {& t6 S5 R* \[size=1em]    virtual InterfaceU1* getInterface1()$ `# X) S/ l; T
    [size=1em]    {  J; b! b) |2 D6 X9 J$ Z
    [size=1em]        return this;
    & a( Q" H9 @! A) n  w8 i4 }9 |! i[size=1em]    }
    2 P) B1 y" u5 I! J# H% S7 ?[size=1em]    virtual InterfaceU2* getInterface2()
    % F' s* v2 X1 ?[size=1em]    {1 M4 ~5 {& n* P0 T
    # ]4 T+ V# C/ f5 d6 \! @
    [size=1em]        return this;1 H3 C, j2 P. J
    [size=1em]    }
    : r! K, ^3 d) }3 ?( l[size=1em]    virtual void func1()/ f4 h. f" J% U# h1 h: p
    [size=1em]    {
    3 b  O1 {. i) H' [& ^- o[size=1em]        printf("%s", "func1");3 Y- X" v" V( c5 y9 J
    [size=1em]    }% s' J# h. F8 p

    / f2 W2 B0 Q! I! m! j2 j0 Y% W! e; i1 y[size=1em]    virtual void func2(): j( o" R! ]! N9 y: {. m, g
    [size=1em]    {! W, ~- Z& _8 f' O0 C( Q
    [size=1em]        printf("%s", "func2");
    . W$ S% g4 j; \- }$ H[size=1em]    }
      k* C& M, T' @0 B! B- p. d0 v[size=1em]}! s- A1 P/ ~, g7 p. q0 s
    # q1 z) @- h! b* U. |: _( R" Q

    7 c4 ]% y- P2 P% D/ x9 k# N

    5 u) N, W2 N7 Z  H
    4 ^7 d0 L* z9 {4 o) K假设有如下代码:' v- x1 c  w% C( Q
    [backcolor=white !important][size=1em]PHP code) h0 z( y5 K% ~
    [color=white !important][size=1em]?

    / _! d# W/ ~& m  e
    [size=1em]1

    % I$ o6 Z  g. ~% M5 _$ d& O
    [size=1em]2

      Q% }4 p4 k" Y# Y( X
    [size=1em][size=1em]Base* pBase = new Base();4 N( T8 c% u2 n' q
    [size=1em]pBase->getInterface1()->func1();
    9 T6 j4 {9 x% `% s
    : R% }* S  x( l8 D2 K) X

    6 z0 P$ z3 r4 m" R4 o# U* z3 |8 g2 _: ~
    $ c; n7 b7 K: ?  Q3 ~
    其实以上代码等于:
    & T! N6 y, b5 F# K1 _3 H' |[backcolor=white !important][size=1em]PHP code2 I+ ]$ N  C+ h. B
    [color=white !important][size=1em]?

    8 l! c: I8 X: ~7 q( I% }4 l! |- x
    [size=1em]1
    6 H% w' m$ |; o* C) o0 C
    [size=1em]2
    , u" @, u3 r* g! ]+ Z0 |
    [size=1em]3
    # x& R5 k0 N% @% r% }  `
    [size=1em][size=1em]Base* pBase = new Base();  N3 |9 l& e/ y  a
    [size=1em]InterfaceU1* pInterface1 = pBase->getInterface1();0 F# _) J" H  Y- e2 G
    [size=1em]pInterface1->func1();- _  T5 P  Q/ Y/ `( N
    + w1 e; o% N' _1 y; p$ a
    : G3 |5 {% E+ ~6 F; _

    : H" p& G0 r8 \  k: m$ z
    5 X8 @# e+ C5 X) N6 K# H
    5 [  Q+ [' {7 J) |+ W4 g" J, c+ k5 U! Z9 j8 M5 o- {1 s2 u
    C++编译后,Base类的虚函数表如下:
      [$ z' Q4 }  l' T$ f[backcolor=white !important][size=1em]PHP code6 [: H9 T" k) S
    [color=white !important][size=1em]?
    8 K. q0 V# ?0 @8 }
    [size=1em]1
    % Z2 ^- |# _" N- E$ D9 \
    [size=1em]2

    7 E0 C, I; ?, ~
    [size=1em]3
    5 q) m7 X4 N) I# \' A
    [size=1em]4

    2 D4 P/ U. C# N, {0 b3 P
    [size=1em][size=1em]  
    # D( |% H4 I- Z& K# r[size=1em]vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|
    4 L* N- }0 t7 U0 Q# b8 l. v[size=1em]vTable:InterfaceU1 |Base::func1()|
    7 r3 R8 z! O" u* M  q: ~* ~% n[size=1em]vTable:InterfaceU2 |Base::func2()|% p# v' e# x; X6 N

    ) |8 G* C+ r; G! |+ d8 |
    & w) R  f- ~3 J$ K2 D; J
    0 K0 p. A' I! @
    # o1 U, j( o3 g# K/ h( x  V4 N
      O) l" O" W2 x: j0 J
    如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。
    6 ~* B. g3 c% I; d- C2 ]2 m6 @. `但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。6 g  j* `  D0 v9 w/ X: @: z
    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?# n$ f- H5 H0 Q& J$ h( U4 a6 e! I
    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定), ?) P5 D$ \' P  v) j' K
    4 \$ n% A3 y- O- V* w7 A( P
    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-7-13 18:23 , Processed in 0.298990 second(s), 54 queries .

    回顶部