假设我们有以下计划:
class A
{ public:
virtual fun(){};
};
class B:public A
{ public:
virtual fun(){};
};
int main()
{
A a1;
B b1;
}
我的问题是,当我们运行此程序时,会创建多少vtables
和多少vptrs
?
答案 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 ++标准没有谈到vptr
或vtable
,虚拟机制被省略为编译器的实现细节。实际上,编译器可以在不使用vptr
或vtable
的情况下实现它。但是,几乎所有已知的编译器都使用vptr
和vtable
来实现它。
鉴于上述情况,回答你的问题:
每个班级都有自己的虚拟桌子 虽然每个对象都有自己的虚拟指针。
答案 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级)。