QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1632|回复: 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! l& E3 ~. t2 ^5 `# ]
    [size=1em]      InterfaceU1
    . `9 L. @7 E9 E' S& _  U[size=1em]  {  |( V& f5 r) }* T- }# n5 ?4 @4 x- H, W
    [size=1em]  public:( O4 t- A$ X: M6 @# j* a
    [size=1em]      virtual void func1() = 0;- g) d* b( q" e  [7 w( _
    [size=1em]  }; P/ p/ {8 S% M( L/ t. v
    0 [9 T) U" G( N7 F
    [size=1em]  class
    4 m; |: j6 U& @' U/ P2 v+ o- ?4 n[size=1em]      InterfaceU2" j) F0 i! Q+ z5 z; Y- n& t) s
    [size=1em]  {1 }* n- t4 r! L, P0 N: z  D2 a
    [size=1em]  public:
    ) I& D- O1 A! ^' D% n' r8 }[size=1em]      virtual void func2() = 0;+ V7 @0 N6 |, u! T$ J
    [size=1em]  }
    * E# [6 A. |6 A( W
    7 b3 ]( O" \" V- l  ^- U[size=1em]  class
    - K5 Y. m. u3 L: {( h( x; g[size=1em]    Wrapper; @3 \( }/ Z* ~% c/ q/ e
    [size=1em]  {
    ' U. L% T. g1 V, Y3 ~[size=1em]  public:
    # {1 X: I: U( z[size=1em]      virtual InterfaceU1* getInterface1() = 0;; R, G& W3 Y# j& @! b* Z+ J' y0 {
    [size=1em]      virtual InterfaceU2* getInterface2() = 0;. ^. q# e" _1 N  b; H0 l
    [size=1em]  }
    . D2 _+ L# @: \5 S3 J: H8 P! k- Y1 R, Z5 H6 X4 D" L! Z+ }
    [size=1em]  class3 t* H+ [% h! K6 q& z
    [size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2
    " f3 x) {! m) J9 U[size=1em]  {6 F0 I, s; x$ E) P1 u
    [size=1em]  public:3 _2 T! q6 ~, W8 @, Z0 a
    [size=1em]      virtual InterfaceU1* getInterface1()$ q3 T" ~- f0 c2 s# `- |8 r
    [size=1em]      {
    9 R) Y, ~! ?1 t. [/ ^) L2 A' L[size=1em]          return this;
    5 ]' G0 h3 t0 [' I; z. O1 h[size=1em]      }4 k# ]$ u+ j. Q6 p+ D7 D
    [size=1em]      virtual InterfaceU2* getInterface2()
    / _. S( H! k8 A  U* g7 F[size=1em]      {/ |; P2 w; {! s: t1 F4 r6 j- D' @

    , t1 b9 R6 _. o$ K% x+ U[size=1em]          return this;5 L$ E5 `3 K, x# X8 g, g
    [size=1em]     }/ d+ {3 q/ n+ B: g( C9 r( H0 d
    [size=1em]     virtual void func1()
    # a' s/ B' x' W, C! J: M[size=1em]     {/ s( c2 @& N+ e% r1 j
    [size=1em]         printf("%s", "func1");
    % P( j, G4 H1 l& t. k7 [/ ^2 g* |[size=1em]     }
    + I& o6 [$ y* V/ y
    2 w5 s4 ~  K7 b& O8 _4 g4 i3 y6 J. W6 h[size=1em]     virtual void func2()
    ) k1 d& a  u! _[size=1em]     {
    6 r$ c1 k& @1 Y4 D[size=1em]        printf("%s", "func2");
    6 z8 B) u' l9 @/ j[size=1em]     }
    ! {0 T1 O. H, @1 P+ E: u[size=1em] }' P) D1 w! d" V* W7 i* w6 y6 G" c; M  s
    / E! I. A% T3 s3 r% w, A
    1 s' U8 G+ E( n  i- @7 C
    5 V0 S6 t$ `( R% p1 [3 @

    5 e2 o" l. X; @3 A; `假设有如下代码:9 t' D/ E2 _6 S2 K& B9 a
    [backcolor=white !important][size=1em]PHP code) ~% m. N  G: W" p
    [color=white !important][size=1em]?

    9 |7 h3 g( U9 P. u2 m* t$ @/ _6 \
    [size=1em]1

    8 f  D4 K+ k# N# v  w
    [size=1em]2

    ) Q% f  `0 k' p, ^
    [size=1em][size=1em]Base* pBase = new Base();6 s3 L. V- G7 J& @; ?4 d
    [size=1em]pBase->getInterface1()->func1();' f; n2 Z8 |/ [- R1 j5 m+ ~

    ! _9 a4 Z5 I! _1 r

    9 y* @  Y' T7 m3 X+ n/ m7 k' K! r) H# F3 H. Y0 p# x

    2 y3 i& B; i, ~  B1 k2 k2 p6 i其实以上代码等于:3 Q: i/ v1 B! J! o' J& i; s
    [backcolor=white !important][size=1em]PHP code; Z3 k! R% d6 j$ @" y- d! z- ]
    [color=white !important][size=1em]?
    / E( f, s8 [9 Y& M  u. ]* F) J4 `
    [size=1em]1
    ' B2 w: h- n) b8 N2 J5 a, d
    [size=1em]2

    4 a" g( _6 u# b5 _5 D% m% d. \
    [size=1em]3
    9 d+ Y6 R0 `5 [! E. y
    [size=1em][size=1em] Base* pBase = new Base();
    - y& k; ]0 n* h* D+ `- E3 I7 d[size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();6 z2 ]: E0 i( A
    [size=1em] pInterface1->func1();
    . `9 i8 ^8 p* W; L1 f9 n. `2 s
    - Q; E: F" m7 n( T: u- F1 S
    , `' E  _) c& `6 H: T9 z

    7 b, p9 z/ N- Y
    - U- S5 v" Y3 V: e# w5 o. o) d4 f9 [7 w) |
    / ?- y" J9 {7 u1 N/ Q- w7 w- q& A0 a& n
                  C++编译后,Base类的虚函数表如下:
    ( s0 A& v( e5 \3 _/ b5 t( b[backcolor=white !important][size=1em]         PHP code0 l+ E+ h# i" }2 |- K! K. B+ B" d
    [color=white !important][size=1em]?

    6 y' y1 ^8 v5 y$ K- F" C' W
    [size=1em]1
    8 K+ _5 U$ Z1 z$ z
    [size=1em]2

    7 c3 p- ?) N* ]0 }2 E/ O0 P: i
    [size=1em]3

    0 h# |2 }0 u" i% @  D% G# X
    [size=1em]4

    1 G  ?: `, Z+ W6 J, r5 ?
    [size=1em][size=1em]  
    0 D# b4 s9 V- K( j[size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|
    : `. o8 s  H- g' B4 M4 m[size=1em]  vTable:InterfaceU1 |Base::func1()|+ @& ?( T" \. A, d2 [/ B
    [size=1em]  vTable:InterfaceU2 |Base::func2()|7 p, U0 Y% b  J+ w* W
    9 G7 U1 f; F0 K2 ~4 q+ T
    8 H5 o1 g" P1 O4 z$ [. O- d' q! Q

    ( h8 a) z' \' }2 e! F* L
    / ^* g8 ~. w6 }# k* N  T/ n6 e/ A7 \! b6 V9 G7 s# `7 l$ B
         如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。3 n$ {8 y0 N, G1 P8 ^, d
        但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。
    & ~& y4 u1 G+ ]+ R" h1 W  A% _8 N2 c    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?0 e' V  }- I1 w9 [9 Q$ I
        C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)6 F2 T) i" m4 C* F2 c' _9 j
    4 }9 `6 k: W$ B) x; `. P2 ^
    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 03:06 , Processed in 0.410716 second(s), 50 queries .

    回顶部