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

14ifxucb  于 2023-06-07  发布在  其他
关注(0)|答案(6)|浏览(206)

假设我们有下面的程序:

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

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

4szc88ey

4szc88ey1#

它严重依赖于实现,但通常你会得到一个vtable对象每个类有任何虚函数(类没有虚函数或基地不需要他们),和一个vptr每个对象的类与一个vtable(指向类的vtable)。
如果您有多个继承和虚基类,事情会变得更加复杂--这可以通过多种方式实现。一些实现对每个额外的基类使用一个附加的vtable(所以最终每个基类每个类都有一个vtable),而其他实现则使用一个包含额外信息的vtable。这可能导致每个对象需要多个vptr。
B中的virtual关键字是无关紧要的--如果函数在基类中是虚的,那么它在派生类中也是虚的。

7kqas0il

7kqas0il2#

这个程序可以被优化为完全像这样:

int main(){}

所以,“没有”是一种可能性。

qij5mzcb

qij5mzcb3#

基本上,2。一个用于class A,一个用于class B(vftables),2个vfptr,一个用于a1,一个用于b1

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

注意@R. Martinho Fernandes在优化打开的情况下,您将不会创建任何对象,因此不会创建vfptrs

gcxthw6b

gcxthw6b4#

注意,这是严格依赖于实现的。

C++标准没有谈到vptrvtable,虚拟机制作为编译器的实现细节被排除在外。因此,实际上,编译器可以在不使用vptrvtable的情况下实现它。然而,几乎所有已知的编译器都使用vptrvtable来实现它。
鉴于上述情况,回答您的问题:
每个类都有自己的虚拟表。
而每个对象都有自己的虚拟指针。

ix0qys7i

ix0qys7i5#

只有当基类中至少有一个虚函数时,才会创建虚表,这将以任何方式继承到派生类。即使你从派生类B中删除了virtual关键字也没关系,因为你已经在A中获得了一个virtual fun()。因此,虚拟表的数量将是2(作为其每个类的基础),并且虚拟ptr的数量也将是2(作为其每个对象的基础)。VTABLE for A---v_ptr*,A::fun()
B的& VTABLE--- V_ptr*(继承自A),B::fun()/* B可以访问A::fun和B的fun(),但由于我们提到A::fun()是虚拟的,B的虚拟表填充了函数fun()的最派生版本,它只不过是B::fun()。希望这能消除你的疑虑

kse8i1jr

kse8i1jr6#

将有2个vtables,一个用于A类,一个用于B类。将有3个vptrs,一个在a1中,两个在b1中(一个指向class Avtable,另一个指向class Bvtable)。

相关问题