QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2004|回复: 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
    2 V$ w8 M$ v1 v6 d: Z& ^! J[size=1em]    InterfaceU1: v4 m) S8 y' I; X; f
    [size=1em]{
    3 R3 O+ M; `2 F# p8 X[size=1em]public:8 I5 Z# S2 _& @& r4 |2 d  E
    [size=1em]    virtual void func1() = 0;! u* N7 @; e6 W9 m$ ]2 E
    [size=1em]}% V8 j+ ]/ n  E

    ( o: u3 D' C4 f[size=1em]class
    1 L& V: e5 {9 W+ _3 i[size=1em]    InterfaceU2
    3 T7 N/ r& W. `& a[size=1em]{. [6 j. s: X: l8 f& c6 A
    [size=1em]public:5 d4 Y0 p$ B% i3 T5 I( [! `
    [size=1em]    virtual void func2() = 0;
    ) n# N( j: J; _8 j7 f+ {6 ?[size=1em]}$ _$ T" L2 @5 [5 I2 T; H) }- q# L

    7 n2 j, B% a0 I[size=1em]class. ?' |6 F6 w3 \5 r# V9 g& L
    [size=1em]    Wrapper2 B8 K& D# B' d4 Z3 e
    [size=1em]{
    0 i5 v- P/ `2 S  n) D[size=1em]public:
    3 O7 P1 ?' h! c. n" M3 M[size=1em]    virtual InterfaceU1* getInterface1() = 0;! f9 V, W' A- C0 r( U
    [size=1em]    virtual InterfaceU2* getInterface2() = 0;, U2 |& I% b- v. K4 L  Q. [
    [size=1em]}5 p% x: C6 I, [4 \2 C9 |

    " J6 s7 I; E2 I$ w[size=1em]class
    ! ~2 J6 A/ [6 c" H7 Y[size=1em]    Base : public Wrapper, public InterfaceU1, public InterfaceU2
    4 C2 R: X0 r9 K4 \! h5 |5 \6 l0 L[size=1em]{
    ; V2 r5 Y$ ^# s% w  R9 v9 G[size=1em]public:/ n1 ~. g, d; y0 F1 i  {
    [size=1em]    virtual InterfaceU1* getInterface1()7 f0 q) x6 l: {2 \: ]! K
    [size=1em]    {/ h/ O2 K3 a- U1 \
    [size=1em]        return this;9 ?' p( H7 P9 m* _0 K
    [size=1em]    }0 I+ ]0 _. @. X
    [size=1em]    virtual InterfaceU2* getInterface2()
    2 x- @2 C0 G4 v" @9 ~[size=1em]    {+ o& U4 E, P( B$ ?8 z! _6 H6 A

    % l. U& J7 |; ~" J( @[size=1em]        return this;
    $ z- {& u$ \% G[size=1em]    }) F( W% t7 H* E/ S+ p0 `
    [size=1em]    virtual void func1()" K5 e: j% H' C* Z" l
    [size=1em]    {
    / v& L4 `" s5 M0 v[size=1em]        printf("%s", "func1");
    * z; f& z. ]0 [$ z[size=1em]    }
    - J1 c3 Q8 J' ~$ I" [7 t) b; @  U7 W
    [size=1em]    virtual void func2()+ u* C' W! v1 j5 S0 J
    [size=1em]    {6 S4 `# r3 D& o' n* c/ T2 g6 K
    [size=1em]        printf("%s", "func2");- G& z( c, }. }9 \! T( e' s5 z
    [size=1em]    }
    7 c# f+ U3 R# A$ q$ k[size=1em]}( ~& h, X8 X' ?5 t' Y  B" b& p

    9 d: K& b+ E# ~" @% N

    $ `: Y. I; n& ~
    7 e: C7 Y' B; v. S1 E, m6 S

    3 j8 w* b0 |8 ~假设有如下代码:* d+ k/ g  \3 @' P' X% M& H
    [backcolor=white !important][size=1em]PHP code: Q' v# {. R" Q
    [color=white !important][size=1em]?

    5 E6 u# L' R8 `$ Q' y
    [size=1em]1
    % q& T/ O% x  c+ A
    [size=1em]2

    * i) _& y8 A; k1 b2 f
    [size=1em][size=1em]Base* pBase = new Base();# M# l0 M% t9 z) `) l- H  X% E
    [size=1em]pBase->getInterface1()->func1();, V& G& V3 @  l: n2 T. s1 i2 f& x
    $ O* T# B( |: V% s

    5 S: _3 M9 R: a6 I7 E
    ! h& ]5 n6 A8 c4 P: Z$ }# G
    1 {' Z5 j; L6 H& d其实以上代码等于:3 u+ B4 b  ~/ I' W
    [backcolor=white !important][size=1em]PHP code  y- [0 h, F- P, |/ C
    [color=white !important][size=1em]?
    % f. E) Q# ^" q( K  ^5 v
    [size=1em]1
    1 z( t  q, \& L$ c3 m
    [size=1em]2

    8 k& D! w$ \4 w  H
    [size=1em]3

    . }% e2 q0 S& I: A+ S: Z
    [size=1em][size=1em]Base* pBase = new Base();
    ( G& z" ~4 o- o2 S$ v0 w[size=1em]InterfaceU1* pInterface1 = pBase->getInterface1();
    4 D8 ?: C4 ]+ Z9 H[size=1em]pInterface1->func1();
    2 [( N2 x. H# x) W, A' F
    & t+ r3 N( X; B# r8 s. j. G3 B

    : P8 _* G0 u0 f' `
    2 X2 R' \& t1 P8 x1 h" A
      L- x: z% G  U1 H  q$ o+ P
    ( f( h( L3 l+ I' C/ p* m3 s% i! S% K& D/ u$ g
    C++编译后,Base类的虚函数表如下:
    7 D/ F) {# z$ J6 d( ]* [0 v  Q( y[backcolor=white !important][size=1em]PHP code
    & O) l- j! Q7 p
    [color=white !important][size=1em]?

    7 m5 B  o( Z$ V) B8 C
    [size=1em]1
    % y* N' Z+ N4 E0 |# O  ^
    [size=1em]2
    : M" S+ R) K( K; r$ z* i5 ?1 f8 H/ n
    [size=1em]3

    4 Y. D& w" K- h- H6 y* Y0 C
    [size=1em]4
    % W8 t! x2 U6 [- g! Z6 A% z5 C
    [size=1em][size=1em]  
    ; S8 T3 X7 P2 v. ^6 u  @0 B[size=1em]vTable:Wrapper     |Base::getInterface1()|Base::getInterface2()|Base::func1()|Base::func2()|
    % l/ {! ?* r4 X1 g[size=1em]vTable:InterfaceU1 |Base::func1()|
    ! o5 F2 n% H: A& R" X! e[size=1em]vTable:InterfaceU2 |Base::func2()|
    7 |& k6 G; L: L! u- q' j, s
    3 m( [1 v. m9 H' `5 v1 F) ?

    8 U$ B  J9 {! i" U" M! E5 J% v0 v8 |
    $ ]/ ?4 j* T5 X. S
    ) W- r8 J- N$ [% I% A- c; d1 r, n& I/ D+ Q1 L; ^8 Q1 }
    如果单继承情况下 ((InterfaceU1*) pObj)->func1() 很好理解,只需要pObj的vptr[0]处的函数地址即可。
    , x1 V: l% R; P% ?9 p但是多继承情况下,返回的指针pObj 如果用 ((InterfaceU1*) pObj)->func1()  如果依旧使用vptr[0] 则完全错误。
    6 `: Z, D# F( X# i7 u* IC++是如何得到当前应该使用vptr[??]位置的函数地址呢?" o- g3 z8 q8 q. j& P& n
    C++会动态的根据this的当前类型修改所用的是哪张虚表吗?(或者说,存在这种动态的判断吗。编译器是否无法确定)) ~! V# l1 R# ^& z' b7 }
    : h! Y, L/ T% @! j
    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-11 00:42 , Processed in 0.389803 second(s), 53 queries .

    回顶部