QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1670|回复: 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
    2 a8 Z# Y8 U% \8 o( P+ F[size=1em]      InterfaceU14 k- q. j  S1 T
    [size=1em]  {
    / m5 [2 P' p5 h7 b. {: c# m' e, w[size=1em]  public:# N; J. ?0 J8 Q) @
    [size=1em]      virtual void func1() = 0;
    * \  X6 T+ T! }* U4 W% l9 P9 A; Y[size=1em]  }1 j( Q  m6 X* t* o, G! \1 ^+ G

    ; Q1 }* @, y3 D' R+ Y  ~[size=1em]  class
    + B! X+ R/ w! C! t[size=1em]      InterfaceU2
    7 @2 O* K: ~3 ]9 Z! @[size=1em]  {
    9 _- D" D) D* n5 S- y3 I[size=1em]  public:
    ! f8 q  m: a1 \  w  R' M. K" f! b3 a[size=1em]      virtual void func2() = 0;7 l! k: e* \  t: [. Z! J
    [size=1em]  }% u! Q; O( N+ }  B% `
    2 _- s/ w4 J' E- m
    [size=1em]  class
    : I3 v7 A" D/ ~$ x& R4 @[size=1em]    Wrapper
    9 S* D3 ?' ^  ~8 R& z: A[size=1em]  {# z2 Q, v7 K3 C. p+ m# h/ s  E
    [size=1em]  public:
    9 ~# F, s# }+ P( ^: [[size=1em]      virtual InterfaceU1* getInterface1() = 0;# J" A! h, d' g+ y2 `' B& N5 C8 t
    [size=1em]      virtual InterfaceU2* getInterface2() = 0;
    " Z( S- n4 y! K4 @& K" }1 C* _[size=1em]  }) s+ T- @; p; \: x! v

    # I3 F; U3 N. m/ `* f' r[size=1em]  class) C* m% `: X' C0 w* }* t
    [size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2: b2 N: F! V( |. ~/ b
    [size=1em]  {
    % T) B4 h6 F8 x3 A& g[size=1em]  public:0 ^" w+ U% R, J5 B& w
    [size=1em]      virtual InterfaceU1* getInterface1()
    ! R  V; ~, ?! s% ~4 [9 t! q' ?[size=1em]      {
    # X! C0 o$ M" |/ R0 R5 o6 S/ h[size=1em]          return this;
    % [( C& R% F4 ], O- }[size=1em]      }) x; ^0 w7 A/ l& [
    [size=1em]      virtual InterfaceU2* getInterface2()
    : {; X, @2 j% W' q! e! a+ V[size=1em]      {/ @2 j6 t0 T% I7 j* q

    3 E6 G: a# k8 q[size=1em]          return this;
    4 x5 D) J! d% n" [$ D2 O[size=1em]     }
    # [2 M" N; ^- d3 U% Y[size=1em]     virtual void func1()
    0 O8 U- p* Y: {+ h" _4 N[size=1em]     {
    - n; `% c" u* S, P$ {  P[size=1em]         printf("%s", "func1");
    / V, i# M( x+ _5 d, g7 I* W0 T5 y[size=1em]     }3 R0 ?* l" t; D* v& ^
    " U3 G- D/ N3 v4 c+ b/ |% i! f& |
    [size=1em]     virtual void func2()" M9 J; q* ]# N/ G! a1 c. W  Q
    [size=1em]     {
    : }5 R  C! ?" p[size=1em]        printf("%s", "func2");
    / V* |( N: _% J$ P% c" D; q* r[size=1em]     }
    ) `; q! O/ I6 i+ H. ~" E[size=1em] }
    % V3 o  H9 n6 `; K* n( R9 ?+ x! {9 y
    / S: e: F9 n' C9 i7 A. f- z! R0 N' }( c/ E

    8 u  F8 }6 Z' O1 F/ h7 @
    9 G2 Y6 e+ ~( L$ N5 a) G
    1 q+ x$ j7 j1 J6 ]2 _
    假设有如下代码:: W1 s8 H7 O1 F3 o8 y
    [backcolor=white !important][size=1em]PHP code2 ]" G: J! G$ K) c0 B) u
    [color=white !important][size=1em]?
    5 U6 r2 @3 d" T# k7 p$ ?
    [size=1em]1
    . D$ v* w4 H' c% I( Y
    [size=1em]2

    % L5 @/ q. W* m  Z2 g
    [size=1em][size=1em]Base* pBase = new Base();
      c3 g( R# ?. ~5 e. W, a7 s2 {[size=1em]pBase->getInterface1()->func1();
    5 l$ X$ @7 D7 v0 O9 i2 y
    % l* Q# @3 w7 Z7 ~! z/ I& r

    7 n( O  `2 C% W9 T6 A7 T* b1 b1 s, y. X3 C
    / u$ E  n8 U2 E+ h5 N, b
    其实以上代码等于:, Y; V. |& G; n4 _/ i1 F
    [backcolor=white !important][size=1em]PHP code
    ; i3 c) y, D$ M! k/ N- h& B' [4 |
    [color=white !important][size=1em]?
    1 o# w8 m  G3 @9 a- g* w* J
    [size=1em]1

    , t7 ^2 R- n8 k
    [size=1em]2
    / k: O6 ]7 t# a; H
    [size=1em]3

    & d/ b6 G6 h6 g6 a# r# @
    [size=1em][size=1em] Base* pBase = new Base();
    " G6 X) D0 m) A0 M6 s4 R! y[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();9 k' w" u1 M; ~- A0 e8 ?* F5 h
    [size=1em] pInterface1->func1();
    $ [- b1 Q+ E& p- P$ I! U8 n  ]
    + x, E" m8 b9 |" R; P1 @
    & u- H  e- b* D$ I
    6 a* @/ Y; g$ V0 B1 i
    0 W/ n# c$ i0 ^
    9 J; J; j& K7 e4 K

    , \5 X6 o; `$ j* F1 J4 x0 I7 n8 v              C++编译后,Base类的虚函数表如下:
    2 h3 A5 C* z4 n0 J[backcolor=white !important][size=1em]         PHP code
    + O  }$ z* B4 ~1 q, j
    [color=white !important][size=1em]?
    4 j9 P2 m4 P' v+ ^& E4 G/ T
    [size=1em]1

    ' ]) c* k+ n* [
    [size=1em]2

    4 Q. w- v( k* a0 ^) h- a; u7 x
    [size=1em]3
    0 ~2 T/ j1 Y4 \* }; \% @1 R. ]4 f
    [size=1em]4

    ' I& d6 d/ X4 u8 d
    [size=1em][size=1em]  
    $ A3 D- g* N% a4 h4 c[size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|- ~3 ^8 W- J; ?3 e8 J3 i5 V
    [size=1em]  vTable:InterfaceU1 |Base::func1()|
    3 E- N7 Z! d3 A- T[size=1em]  vTable:InterfaceU2 |Base::func2()|! R" E, c- k+ {# Y) R. t) }* x
    & H( M% h$ V8 n' `

    ( ~8 }/ x' W+ z  I1 x% F6 a( X: U
    + _+ `" \( G5 Y: Z8 X
    * C& p5 W( A6 w( `% T* m" S
    * J5 W9 F0 Y0 K4 N     如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。
    ' n, V3 K5 u" @& x    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。/ ?7 Z3 V/ {. G3 d% ]9 h& H8 E
        C++是如何得到当前应该使用vptr[??]位置的函数地址呢?
    , S/ j- @$ @& N/ x! S  ]1 M    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)
    & l, z& w$ o) j3 q. L8 Z
    " w1 M) t& y6 N0 U# f0 Y
    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-17 12:10 , Processed in 0.427992 second(s), 50 queries .

    回顶部