C ++程序中的虚拟表和虚拟指针的数量

时间:2012-01-19 19:24:37

标签: c++ virtual vtable vptr

假设我们有以下计划:

class A
{     public:
      virtual fun(){};
};
class B:public A
{     public:
     virtual fun(){};
};
int main()
{
     A a1;
     B b1;
 }

我的问题是,当我们运行此程序时,会创建多少vtables和多少vptrs

6 个答案:

答案 0 :(得分:13)

这个程序可以优化到这个程序:

int main(){}

所以,“无”是可能的。

答案 1 :(得分:9)

它严重依赖于实现,但通常你会得到一个具有任何虚函数的类的vtable对象(没有虚函数或基类的类不需要它们),并且每个类的一个vptr都有一个vtable (指着班级的表格。)

如果您有多个继承和虚拟基类,事情会变得更复杂 - 可以通过多种方式实现。有些实现每个附加基类使用一个额外的vtable(因此每个类最终得到每个基类的vtable),而其他实现使用一个带有额外信息的vtable。这可能导致每个对象需要多个vpt。

B中的virtual关键字是无关紧要的 - 如果该函数在基类中是虚函数,则它在派生类中将是虚拟的。

答案 2 :(得分:8)

基本上,2.一个用于class A,一个用于class B(vftables)和2个vfptrs,一个用于a1,另一个用于b1

但是,这不是标准规定,所以你也可以没有。 (通常实现使用vftables,但没有强制要求。

注意@R。 Martinho Fernandes在进行优化后,您将没有创建任何对象,因此没有vfptrs

答案 3 :(得分:4)

请注意,这完全取决于实施。
C ++标准没有谈到vptrvtable,虚拟机制被省略为编译器的实现细节。实际上,编译器可以在不使用vptrvtable的情况下实现它。但是,几乎所有已知的编译器都使用vptrvtable来实现它。

鉴于上述情况,回答你的问题:

每个班级都有自己的虚拟桌子 虽然每个对象都有自己的虚拟指针。

答案 4 :(得分:3)

只有当Base类中存在至少1个虚函数时才会创建虚拟表,这将是继承到派生类的任何方式。即使你从派生类B中删除虚拟关键字也无关紧要因为你已经拥有了A中的虚拟乐趣() 因此,虚拟表的数量将是2(作为每个类的基础),虚拟ptrs的数量也将是2,作为每个对象的基础。 VTABLE for A --- v_ptr *,A :: fun()

&安培; VTABLE for B --- V_ptr *(继承自A),B :: fun()/ * B可以访问A :: fun& B的乐趣(),但是因为我们提到了A :: fun(),因为虚拟B的虚拟表充满了函数的派生版本fun(),这只不过是B :: fun()。希望这清除你的疑问

答案 5 :(得分:1)

将有2 vtables,一个用于 A类,另一个用于 B类。并且将有3个vptrs,一个在a1中,两个在b1中(一个指向 A类的vtable ,另一个指向vtable B级)。

相关问题