运行时调用虚函数(std c ++)

ust*_*ion 1 c++ virtual gcc function

vtable当基类具有虚函数时,是所有基类/派生类的开销.vtable应该包含一系列指向这些virtual函数的函数指针.另外vtable是"每个类一个"而不是"每个对象一个".

现在假设创建了这样一个类的对象.它将virtual在运行时在某个内存位置获取该类函数的新副本.由于vtable是函数指针的集合,它将被更新以反映这一点.如果创建了同一个类的另一个对象,那么它将再次拥有virtual一些其他内存位置中的函数的新副本

由于vtable是"每个类一个"而不是"每个实例一个",它如何指向不同实例的正确位置?

Luc*_*ore 8

这很简单...... vftable本身就是one-per-class指针one-per-instance.两个相同类型的实例将使其vftable指针指向同一位置.

class A
{
   virtual void foo();
   virtual void goo();
}

class B : public A
{
   virtual void foo();
}
Run Code Online (Sandbox Code Playgroud)

在记忆中,您将拥有:

vftable for A:  

+----------+---------+
|   0x01   |  0x02   |
+----------+---------+
  &A::foo()  &A::goo()

vftable for B:

+----------+---------+
|   0x11   |  0x12   |
+----------+---------+
  &B::foo()  &A::goo()
Run Code Online (Sandbox Code Playgroud)

假设您创建了两个对象:

A a;
B b;
Run Code Online (Sandbox Code Playgroud)

a的第一个成员将是:

vftableptr: 0x01
Run Code Online (Sandbox Code Playgroud)

b的第一个成员将是

vftableptr: 0x11
Run Code Online (Sandbox Code Playgroud)

通常,实现多态性获取地址vftable,添加函数偏移量(例如,如果我们调用goo(),偏移量为1),并跳转到该位置.由于对象具有不同的类型,它们将指向不同的位置,尽管vftables(它们是不同的)可以包含类似的成员.

重要说明:值是伪造的,偏移量不是1地址0x01等,我选择它们来说明一点.


Mar*_*k B 5

对于类的每个实例都没有单独的函数,因此vtable始终指向相同的函数.每个类实例都有一个指向vtable的指针.