QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1690|回复: 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" T6 @2 [: K8 e5 P6 ~
    [size=1em]      InterfaceU16 J9 V6 [  \" J" a4 w- m1 P; l
    [size=1em]  {
    5 y: S6 p% Y; A4 ]9 `; _  U0 V; `[size=1em]  public:  o& N2 }% f' c  S& L6 b
    [size=1em]      virtual void func1() = 0;
    4 `8 R9 n* v/ U7 n" B. r[size=1em]  }1 I5 S% P) o2 Z$ _- x
    ! K! \: j6 J% A$ z/ ~
    [size=1em]  class/ |. E: I" }* V# G4 T4 D6 A  W
    [size=1em]      InterfaceU2
    5 u/ a; z% R7 a[size=1em]  {4 M3 f0 I: B8 j+ u- z
    [size=1em]  public:- V# T+ V2 u1 n5 q
    [size=1em]      virtual void func2() = 0;# ^) d. R0 S. }: O, b
    [size=1em]  }
    9 U  ]$ M( W# m1 b+ S% f7 v( y- X# Q% `& A
    [size=1em]  class
    1 s: B: V+ r. A6 G0 L( W[size=1em]    Wrapper. E/ U) w' \- e5 ]3 p4 l
    [size=1em]  {0 E. D: F4 ?2 C3 J
    [size=1em]  public:7 w0 l- u, C8 `+ l% A; V' M
    [size=1em]      virtual InterfaceU1* getInterface1() = 0;# l. i9 V- Z+ Y+ K, @- Y- F3 V6 N
    [size=1em]      virtual InterfaceU2* getInterface2() = 0;
    2 D5 t) ~1 d# l7 ]0 S8 J[size=1em]  }0 S" e$ A2 C6 _

    2 a- b+ _1 w; A. l/ T8 A[size=1em]  class( W5 L% L7 j; B9 }: B  {  h
    [size=1em]      Base : public Wrapper, public InterfaceU1, public InterfaceU2
    1 f( ?* t: x; M9 b! v6 b. u[size=1em]  {
    9 ?. J8 x7 ?# _. d[size=1em]  public:$ W" [) `$ p! z) T
    [size=1em]      virtual InterfaceU1* getInterface1()' O! w/ }. G# E4 I) K
    [size=1em]      {
    & e8 D" Z  x1 e# W. G0 b0 S! E; l[size=1em]          return this;: @' a1 p0 ?, r! s- e
    [size=1em]      }$ n$ d& z2 e5 b; K
    [size=1em]      virtual InterfaceU2* getInterface2()
      t: R6 X) `5 E" k; Z& d[size=1em]      {
    , x8 J; \3 E, h1 D$ |5 A7 D" H, Z. F4 s# g
    [size=1em]          return this;3 [, k. |( P. w/ r- k, V' w4 K
    [size=1em]     }5 E0 P* X% \8 ^1 L) [
    [size=1em]     virtual void func1()
      H& W9 H" n6 `' l[size=1em]     {9 d& J% ~9 m2 k& o
    [size=1em]         printf("%s", "func1");! [$ Z# c  t$ Z0 p
    [size=1em]     }
    2 F9 {2 j. n) i$ b' S
    0 t$ U$ M4 l9 i, Z# P. t[size=1em]     virtual void func2()! C# Z, u1 K7 u
    [size=1em]     {
    ; o* n! M; w7 e1 i! J[size=1em]        printf("%s", "func2");9 ?/ y2 ]' h  Y% K
    [size=1em]     }
    9 L. P0 p4 _' |$ z[size=1em] }
    8 w3 t) l; J8 E# k" N1 ]8 f* T- i4 f5 |; ^  y9 u) s

    ' q: \" y, D. {7 O- X' E6 N1 R
    ( ]: v' V5 j' S, h
    . K3 G" L# Y- j" p' k
    假设有如下代码:
    : Q7 `! V5 R: r& \& J' T[backcolor=white !important][size=1em]PHP code
    ; Q) K7 ?4 {( r2 F
    [color=white !important][size=1em]?
    0 n: t3 u& N8 x9 |$ m' e
    [size=1em]1
    9 Y- |8 D) ?6 {1 T: k0 Q
    [size=1em]2

    6 f1 f$ |2 |1 l9 |: M( N
    [size=1em][size=1em]Base* pBase = new Base();
    4 y# ]2 Q' u. e! H[size=1em]pBase->getInterface1()->func1();( b$ x1 t7 T8 e: Y( h
    6 S5 P6 V, k8 X

    ) j1 y: D+ l6 }% A3 D9 M, @$ U9 j3 p; @! ~1 e, b

    % U2 X1 e* ]: l% ]5 o9 \其实以上代码等于:; `+ A5 A: n) J
    [backcolor=white !important][size=1em]PHP code
    # B  z" X' b4 s6 C8 c
    [color=white !important][size=1em]?

    . D7 v2 x! s, b9 r
    [size=1em]1
    5 O' I1 I: A+ W3 i& U. ^
    [size=1em]2
    " `9 E) r# }" B3 G0 U' J
    [size=1em]3
      k+ t3 F8 t# `2 h6 j
    [size=1em][size=1em] Base* pBase = new Base();- }' r1 S$ A4 w, u0 ?2 n* ^9 C& N
    [size=1em] InterfaceU1* pInterface1 = pBase->getInterface1();
    * c; h6 ]. E3 s0 X; L2 n' a5 q2 m( h[size=1em] pInterface1->func1();
    % l- w5 b( E3 ^; X, O+ l8 i$ S, t' \+ _" w- ]$ n
    3 @# P9 G) _' V# z. Z/ n. _

    8 U8 @2 V% r8 n+ h2 G
    + J$ U, j' [! W  o0 h1 a
    $ O, i9 K) @3 L$ M% {8 ~# |
    9 F1 T1 I% G3 o! _3 N' ~1 ]# Z1 E              C++编译后,Base类的虚函数表如下:
    ) L. |- ^0 ]3 X1 }[backcolor=white !important][size=1em]         PHP code
    2 R5 p( O! m/ w0 s
    [color=white !important][size=1em]?

    5 b) u  h/ O% p# Y* [
    [size=1em]1

    + J8 j) L- I9 `( i+ E5 H! |. ?+ R/ A8 A
    [size=1em]2

    * G5 D$ i. `4 }$ c: d5 _
    [size=1em]3
    . y: O5 n6 n# x/ y, \/ T
    [size=1em]4
    ' G" {! _! U6 d" ^
    [size=1em][size=1em]  " p1 @! j* h0 e2 s6 Q4 v
    [size=1em]  vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|
    - S. `+ [  b5 f* F[size=1em]  vTable:InterfaceU1 |Base::func1()|! v/ A$ a# J, Y) L2 L" Z: @/ J! x
    [size=1em]  vTable:InterfaceU2 |Base::func2()|7 i* {/ {$ o2 ~/ H+ c' |

    + B1 q6 b1 D2 M$ P: w5 U6 Z0 R
    , M; M+ |: h% [# u: S6 N- P5 ^, W

    1 g/ H' }8 T% L/ A- G
    . L- |  J& H% O1 m4 l4 H2 ~
    " [6 F8 f( e* X* ]+ K1 R9 ]! X     如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。
    . L& a' {% i' W9 a2 H1 L: p    但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。
    : f+ `1 m5 N" T' V4 t# d* C    C++是如何得到当前应该使用vptr[??]位置的函数地址呢?% r8 c! d) ~2 t2 Q. Y
        C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)
    : a8 F/ T: q7 V: K+ j- s4 W7 i
    6 ?+ Y' x1 K; E& n( t
    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 20:12 , Processed in 0.425202 second(s), 50 queries .

    回顶部