QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1776|回复: 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
    ; k, J2 I3 X% w4 J* R( |[size=1em]      InterfaceU1! x: C5 ^+ @. J
    [size=1em]  {$ d/ A( r7 J9 B, W0 l# r
    [size=1em]  public:, ?3 m* U. K/ d8 {$ v( N
    [size=1em]      virtual void func1() = 0;
    5 k6 d% w+ M  j0 ]1 X7 r( e[size=1em]  }, F* x4 X5 ?1 s4 {3 I! _6 s, S3 I

    , X& w; n! _4 l! Z, U3 _6 f[size=1em]  class8 I2 W( f0 F. _; g- `9 s/ m; j
    [size=1em]      InterfaceU2
    / i4 S: W4 k) Z( x; R8 w- m6 L[size=1em]  {
    / I% c* w: b% N+ L+ U[size=1em]  public:
    % ?% H0 I8 ?% w& W8 n$ `8 g[size=1em]      virtual void func2() = 0;5 G- f* M# G: Z4 I2 t
    [size=1em]  }, H  I6 C+ X$ w- G& z, v

    , z% G+ f1 f- \2 Z6 _2 R+ C8 q4 S2 {[size=1em]  class
    / I" @; l9 O- ^! }; M1 M[size=1em]    Wrapper& s1 \0 |. y: E
    [size=1em]  {
    / h  |; L: F8 X% A5 J[size=1em]  public:
    / U& Y+ C: B/ ]  E; K7 W+ C" v8 W[size=1em]      virtual InterfaceU1* getInterface1() = 0;
    / h  U6 S; K6 u* ?- P  |[size=1em]      virtual InterfaceU2* getInterface2() = 0;
    ; a& a* j0 _' u5 X[size=1em]  }
    - [0 ^0 M/ O. T4 j5 v. T
    , J" F3 q" W" D$ q; ], @$ \' k/ S/ L( _[size=1em]  class
    5 T+ H  F. u. H: ?' n1 H[size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2
    " n7 q. b1 M( O9 k- ~, p[size=1em]  {: _8 e& p9 t$ m
    [size=1em]  public:
    1 s, [4 e3 b; e; x" I0 z2 a5 S[size=1em]      virtual InterfaceU1* getInterface1()
    0 J; o- t+ _. G  ]* J7 J( Z3 i4 U[size=1em]      {
    ; l8 y. i% x  w3 `! \7 K0 E[size=1em]          return this;, K! |/ A3 w5 `
    [size=1em]      }% ?( J% f/ @' M
    [size=1em]      virtual InterfaceU2* getInterface2()
    . ]$ b( I+ c" t( V# b+ B9 _[size=1em]      {
    8 Y$ @, f2 o- r4 b+ J- K
    . \# }" o& ~$ \) B& _5 n+ |9 k6 ~[size=1em]          return this;1 f5 O4 S0 W, L' `: `
    [size=1em]     }# O5 M6 w' E1 c2 @9 K3 H
    [size=1em]     virtual void func1()$ Z. k& ?+ P7 E' \
    [size=1em]     {7 S$ h' _+ e7 O6 y+ T
    [size=1em]         printf("%s", "func1");9 [) g. B# {  V  I
    [size=1em]     }
    - E3 V4 W4 m% g2 O& v+ M$ x! \; g; d9 F
    0 c! U% t9 I4 i3 k2 w, Q6 h[size=1em]     virtual void func2()$ ~9 \% J( m& ?) |
    [size=1em]     {; j# U& h* s- n1 i# t& O" I
    [size=1em]        printf("%s", "func2");, V5 W0 }, t0 {* `! S" k
    [size=1em]     }
    ' s* {9 E& w- W, l  n  x" k7 X[size=1em] }6 |: s( J) C( f! [7 I/ D
    * N! A* T3 \. K3 r: ]

    # R; a1 @, D! |0 |! y

    & K1 T0 P8 Y3 }! S6 `6 R4 `
    & u: Y  {1 R4 L假设有如下代码:: y6 ^0 c; ^7 F7 ^3 }& i1 c( C
    [backcolor=white !important][size=1em]PHP code
    # A8 v4 {1 C2 N: N( G: J
    [color=white !important][size=1em]?

    $ D7 o$ f. O; ]8 x- V
    [size=1em]1
    # h. A+ Y* K. K- a  v
    [size=1em]2

    7 R+ T- V: w& U7 e
    [size=1em][size=1em]Base* pBase = new Base();
    * ~3 q0 B; m% v. u- y' J[size=1em]pBase->getInterface1()->func1();4 [1 K) {: ^/ j% b- K: p& \
    4 s/ t1 ]4 U  J( i, I8 I
    2 }2 r! ]$ j  R0 E( J

      @0 L) i4 |! |6 c6 ^3 Q
    # e2 N2 X6 K+ \' @1 [/ Q7 W& F其实以上代码等于:+ i# r: S% L7 N3 b+ L$ D7 v% [
    [backcolor=white !important][size=1em]PHP code' `( ]& Q7 [4 C
    [color=white !important][size=1em]?

    8 o; l( d  p. v4 E; l) v; l, T: N
    [size=1em]1

    - _# z0 o9 z; z6 B9 j  c- t  y
    [size=1em]2
    . d) O' R" Y: P
    [size=1em]3
    # O5 _; m+ B( [" R
    [size=1em][size=1em] Base* pBase = new Base();2 [4 H/ B& |! h( A# R/ X1 V9 \( |
    [size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();
    5 b% K  ~1 S% M/ H, d% I" b: w[size=1em] pInterface1->func1();
    & u1 S6 I) L# q3 R" O. X+ R6 i/ J" g4 f, t3 b
    3 ^. r5 C9 J, Q, F: }$ p

    ' m2 C3 f1 Y9 d- L/ s! l7 o; }& ^: S  _3 P/ E
    % ]7 o, f. |1 @: K0 {

    : t' J3 u. L% A# ?% f5 G. J              C++编译后,Base类的虚函数表如下:
    # e8 s) I# Z( E6 Q* @& t[backcolor=white !important][size=1em]         PHP code
    6 o5 y, B2 j* o: B: a% l
    [color=white !important][size=1em]?
    : O+ v' w8 w$ K0 @
    [size=1em]1

    $ _" L, Z* J# ?# u$ Q: f, Z; y8 N
    [size=1em]2
    - |$ Z( b3 j% u2 g
    [size=1em]3
    2 c6 |2 `# b: C3 t) t2 F
    [size=1em]4

    8 C" {' Y5 }9 y& |; l
    [size=1em][size=1em]  / R! e* a6 r* t1 W: T$ h! `
    [size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|
    9 X7 q' H" x3 y: G! W; V% n" T' ^[size=1em]  vTable:InterfaceU1 |Base::func1()|
    ) x) ^% d7 G3 e& u* _( u9 W[size=1em]  vTable:InterfaceU2 |Base::func2()|
    3 O* T8 L( [5 b9 F7 V) }
    + n' E4 u9 Q( u& |- c/ k  A

    4 U* K2 y6 r8 n+ m% J8 ]
    4 h4 b5 O6 h: Z3 r
    7 w- \+ B$ v# l7 m2 ~; l  c6 g( X2 g# |% g6 m/ b# w, J+ Q
         如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。
    % E& x% [7 B7 D9 g8 U; k    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。+ I0 D7 A4 @% H* L' l- W8 s# u8 _
        C++是如何得到当前应该使用vptr[??]位置的函数地址呢?
    6 ~# `2 N5 t. q3 c) a5 o7 l    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)% ^' J1 b3 b( b1 F

    1 M2 Q* W6 ~/ \5 |+ Q
    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-10-17 08:43 , Processed in 0.908767 second(s), 50 queries .

    回顶部