代码之家  ›  专栏  ›  技术社区  ›  Bruce

C++中成员函数的内存实现

  •  2
  • Bruce  · 技术社区  · 15 年前

    我读了一篇关于虚拟桌子的文章 Wikipedia

    class B1
    {
    public:
      void f0() {}
      virtual void f1() {}
      int int_in_b1;
    };
    
    class B2
    {
    public:
      virtual void f2() {}
      int int_in_b2;
    };
    
    used to derive the following class:
    
    class D : public B1, public B2
    {
    public:
      void d() {}
      void f2() {}  // override B2::f2()
      int int_in_d;
    };
    

    在阅读它之后,我不禁想知道非虚拟成员函数是如何在C++中实现的。有没有一个像v表那样的单独的表来存储所有的函数地址?如果是,那么这个表叫什么?在继承过程中它会发生什么?

    如果不是,那么编译器如何理解这些语句?

    D * d1 = new D;
    d1->f0();    // statement 1
    

    编译器如何解释f0()是B1的函数,既然D公开继承了D,它就可以访问f0()。根据这篇文章,编译器将语句1改为

    (*B1::f0)(d)
    
    3 回复  |  直到 15 年前
        1
  •  7
  •   Amnon    15 年前

    非虚成员函数的实现方式与接受隐藏 this

        2
  •  1
  •   rubenvb    15 年前

    除了 this ,我只能说普通成员函数只是类中的一个内存地址(我甚至相信该类的每个对象在内存中使用相同的“函数指针”,但有自己的变量)。v表是运行时重定向的一种形式,因为编译器不知道什么对象 确切地 它正在处理(显然是由于多态性)。

        3
  •  1
  •   adf88    15 年前

    有没有一个像v表那样的单独的表来存储所有的函数地址?

    f0级 方法是非虚的,编译器知道它的地址,因为只有一种可能。将地址设为0xABCD。然后是密码

    d1->f0();    // statement 1
    

    按照以下说明进行编译:

    // push onto the stack 'this' pointer, as you pointed out the address must
    // be earlier translated from D class to B1 which is not presented here
    push d1
    
    call 0xABCD // call method at known address (jump to this address)