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

发布于 2024-12-28 02:07:09 字数 237 浏览 1 评论 0原文

假设我们有以下程序:

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

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

Let say we have below program:

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

My question is how many vtables and how many vptrs will be created, when we run this program?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

你是暖光i 2025-01-04 02:07:09

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

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

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

Its heavily implementation dependent, but generally you'll get one vtable object per class that has any virtual functions (classes with no virtual functions or bases don't need them), and one vptr per object of a class with a vtable (pointing at the class's vtable).

Things get more complex if you have multiple inheritance and virtual base classes -- which can be implemented many ways. Some implementations use an addition vtable per additional base class (so you end up with a vtable per base class per class), while others use a single vtable with extra info in it. This may result in needing multiple vptrs per object.

The virtual keyword in B is irrelevant -- if the function is virtual in the base class, it will be virtual in the derived classes regardless.

猥琐帝 2025-01-04 02:07:09

该程序可以优化为与此程序完全相同:

int main(){}

因此,“无”是一种可能性。

This program can be optimized to be exactly like this one:

int main(){}

So, "none" is a possibility.

在巴黎塔顶看东京樱花 2025-01-04 02:07:09

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

但是,这不是标准强制要求,因此您也可以不这样做。 (通常实现使用 vftables,但它不是强制的。

注意 @R.Martinho Fernandes,启用优化后,您将不会创建任何对象,因此没有 vfptrs

Basically, 2. One for class A, one for class B (vftables) and 2 vfptrs, one for a1 and one for b1.

However, this is not standard mandated, so you could as well have none. (usually implementations use vftables, but its not mandated.

Note @R. Martinho Fernandes with optimizations on, you will have no objects created, so no vfptrs.

冷了相思 2025-01-04 02:07:09

请注意,这严格依赖于实现。
C++ 标准没有提及 vptrvtable,虚拟机制作为编译器的实现细节被忽略。因此,实际上,编译器可以在不使用 vptrvtable 的情况下实现它。但是,几乎所有已知的编译器都使用 vptrvtable< 来实现它。 /代码>。

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

每个类都有自己的虚拟表。
而每个对象都有自己的虚拟指针。

Note that this is strictly implementation dependent.
C++ Standard does not talk of vptr or vtable, the virtual mechanism is left out as an implementation detail for compilers. So practically, compilers can implement it without using vptr or vtable.However, almost all known compilers implement it using vptr and vtable.

Given the above, to answer your question:

Each class will have its own virtual table.
While each object has its own virtual pointer.

錯遇了你 2025-01-04 02:07:09

仅当基类中至少有 1 个虚拟函数时才会创建虚拟表,该虚拟函数将以任何方式继承到派生类。即使您从派生类 B 中删除 virtual 关键字也没关系,因为您已经在 A 中拥有了 virtual fun() 。
因此,虚拟表的数量将为 2(作为其每个类的基础),虚拟指针的数量也将为 2,作为其每个对象的基础。 A---v_ptr* 、 A::fun()

和 A::fun() 的 VTABLE B 的 VTABLE--- V_ptr*(继承自 A),B::fun()/* B 可以访问 A::fun 和 A::fun()/* B 可以访问 A::fun 和 A::fun()。 B 的 fun(),但由于我们提到 A::fun() 作为虚拟 B 的虚拟表充满了该函数的最派生版本 fun(),它只不过是 B::fun()。希望这能消除您的疑虑,

Virual table will be created only if at least 1 virtual function is there in the Base class, which will be any way inherited to the derived classes. It doesn't matter even if you remove virtual keyword from derived class B because already u are having a virtual fun() in A.
So the number of virtual tables will be 2 (as its per class basis) and number of virtual ptrs will also be 2, as its per object basis. VTABLE for A---v_ptr* , A::fun()

& VTABLE for B--- V_ptr*(which was inherited from A),B::fun()/* B have access to both A::fun & B's fun(), but since we mentioned A::fun() as virtual B's virtual table is filled with the most derived version of the function, fun(), which is nothing but B::fun(). Hope this clears your doubt,

天涯离梦残月幽梦 2025-01-04 02:07:09

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

There will be 2 vtables, one for class A and one for class B. And there will be 3 vptrs, one in a1 and two in b1(one pointing to vtable of class A and other pointing to vtable of class B).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文