问题标签 [vptr]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
228 浏览

c++ - 虚拟类继承对象大小问题

在这里,在这段代码中,ob1 的大小是 16,这很好(因为虚拟指针),但我不明白为什么 ob2 的大小是 24。

我希望 ob2 的大小为 20,但输出为 24

0 投票
3 回答
814 浏览

c++ - 为什么即使不涉及虚函数,虚继承也需要 vtable?

我读了这个问题:C++ Virtual class继承对象大小问题,并且想知道为什么虚拟继承会在类中产生一个额外的vtable指针。

我在这里找到了一篇文章:https ://en.wikipedia.org/wiki/Virtual_inheritance

它告诉我们:

然而,在一般情况下,这个偏移量只能在运行时知道,......

我不明白这里与运行时相关的内容。完整的类继承层次结构在编译时是已知的。我了解虚拟函数和基指针的使用,但虚拟继承没有这样的事情。

有人可以解释为什么某些编译器(Clang/GCC)使用 vtable 实现虚拟继承以及在运行时如何使用它?

顺便说一句,我也看到了这个问题:vtable in case of virtual inheritance,但它只指向与虚函数相关的答案,这不是我的问题。

0 投票
2 回答
122 浏览

c++ - 在没有放置 new 运算符的情况下在预分配的内存上使用虚拟函数初始化对象 - 这可能吗?如果不是,为什么

假设有一个简单的类层次结构和一个使用派生类的状态对象;

现在,让我们假设有一个分配器,它不知道类型,只返回 0 初始化的所需大小的分配块内存。

现在,要正确初始化 vtable 指针,我们必须构造对象。我已经看到它通过放置新运算符完成。它似乎确实有效。

但是,我很感兴趣为什么如果我像这样构造状态对象

状态已完美初始化,我看到值设置为 1 和 2。但 _vfprt 为 0。即使我进入构造函数,this指针似乎已正确设置所有内容,_vfprt 指向正确的方法和所有内容。

但是当我从构造函数返回时,_vfprt 无法复制到 State 对象。其他一切都在那里。但 _vfprt 为 0;所以我只是想知道是否有一个特殊的神奇复制构造函数在使用 new() 运算符时被调用。如果有,我该如何使用它。

我在我的应用程序中到处使用这种初始化,老实说,为了支持一个小类而在所有地方添加新的位置是一件很痛苦的事。{} 调用更简洁(更短),它使分配调用更容易。如果无法完成这项工作,我可以接受。我只是对为什么在我们从构造函数返回后没有将 vtable 指针复制回来感到困惑。

如果有人能解释为什么会发生这种情况,那就太好了。谢谢!

0 投票
0 回答
64 浏览

c++ - 强制虚拟和非虚拟基类的特定排列

如果我有这样的代码:

当我现在创建一个 C 实例时,它的内存布局看起来像这样:

但我真正想要的是这样的:

是否有某种关键字来强制继承顺序?

是使用 VC++15 进行编译,问题是我使用了一个大型自动生成的代码库,它用于所有类 void* 指针来“伪造”vtables ...现在我使用该代码库并继承它,这个实例现在需要特殊顺序的内存布局才能与要加载的不同框架一起正常工作。而那个框架需要前面的A数据。

0 投票
2 回答
741 浏览

c++ - 派生类可以有多个指向虚拟表的指针吗?

我正在观看 BackToBasics 演讲:CppCon2019 的Virtual Dispatch 及其替代 方案。演示者说和幻灯片显示(假设我没有误解)派生类从基类继承了一个 vtable 指针,并且还具有自己的 vptr。

当然,从技术上讲,这不是标准规定的,但我让自己有点困惑,我对 sizeof() 的实验似乎也暗示应该只需要一个指针。请有人澄清一下是否有需要多个 vptr 的情况?

谢谢

PS 为了清楚起见,在这种情况下,我们正在考虑更常见的公共继承,而不是虚拟或多重继承(演讲者在演讲的前面部分明确提到了这一点)。

0 投票
1 回答
132 浏览

c++ - 根据 C++ 标准的多态对象的存储布局

我知道如果一个类包含任何虚函数,大多数编译器(如果不是全部)都会向它的对象添加一个 vptr 指针。有的将其添加为第一个元素,有的将其添加为最后一个元素。但是 C++ 标准是否要求使用 vptr 和 vtable?理论上,任何编译器都可以以其他方式实现它吗?如果是这样,关于多态对象的存储布局和整体大小的保证是什么(例如,连续内存块中的所有明确定义的字段(+填充))?

我不知道这在各种 C++ 标准之间是否有所不同,这就是为什么我只添加了通用C++标签。

0 投票
1 回答
92 浏览

c++ - 为什么带有 vptr 的对象要长 12 个字节?

输出是

我希望它长 8 个字节 - vptr 指针。但是剩下的 4 个字节是用来做什么的呢?我发现了很多论坛帖子(都是几年前的),人们在其中讨论了 vprt 类中的对象长 4 或 8 个字节。我还检查了在线 C++ shell - 输出是一样的。

0 投票
1 回答
106 浏览

c++ - C++ 如何获得指向类的虚函数表的指针?

鉴于:

例子.h

例子.cpp

假设我想从“scratch”创建一个Derived的实例。由于它包含一个虚函数,来自Base,我将如何获取其虚函数表的地址,以便我可以执行以下操作:

主文件

这个编译器是特定的吗?如果是这样,如果有人熟悉它,我正在使用 MinGW。

0 投票
2 回答
73 浏览

c++ - c++ 中的指针“this”是否支持虚拟机制?

考虑一下:

我认为在 C++ 中的实现B::f()是这样的:

下面的例子中是D::vf()通过虚机制调用的吗?

0 投票
1 回答
77 浏览

c++ - 为什么在虚函数声明中使用不同的返回类型会引发错误而不是导致重新定义?

基类:

派生类:

上面的代码抛出“返回类型不相同/协变错误”。

我读过一些关于它的讨论。这个类似,但他们只说如果返回类型不同/协变,它将破坏代码。 覆盖具有不同返回类型的成员函数

为什么我期望的行为没有发生?

预期行为: Derived 中的 VPTR 指向 Base::f() (我读过如果没有为虚函数提供覆盖,Derived 对象将只使用继承的类版本)。它还隐藏了名称 f() 所以现在这样的调用:

应该调用 Derived::f() 和这样的调用:

应该调用 Base::f() 函数。这似乎不像破坏代码。万一它被升级了,即使那样它也不应该破坏代码,因为两个类的 VPTR 都指向同一个 Base::f()

我能想到的唯一原因是这样的声明(相同的签名和协变/相同的返回类型)被保留用于覆盖虚拟方法,我们不能使用它来导致我期望的行为。