问题标签 [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 投票
4 回答
156 浏览

c++ - 是否存在类声明虚拟方法而编译器不需要使用 vptr 的情况?

我想知道是否有可能的优化,即使对象的类型是具有虚拟方法的类,编译器也不需要将 vptr 分配给实例化对象。

例如考虑:

在这个例子中,编译器在编译时肯定知道 pFoo 的类型是什么,所以它不需要为 pFoo 使用 vptr,对吧?有没有更有趣的情况,编译器可以避免使用 vptr?

0 投票
4 回答
463 浏览

c++ - 获取所有现有 vtable 的列表

在我的应用程序中,我有很多空指针(这是由于历史原因,应用程序最初是用纯 C 编写的)。在我的一个模块中,我知道 void-pointers 指向可以从已知基类继承的类的实例,但我不能 100% 确定这一点。因此,对 void 指针执行 dynamic_cast 可能会出现问题。可能,void 指针甚至指向一个普通结构(因此结构中没有 vptr)。

我想调查 void-pointer 指向的内存的前 4 个字节,看看这是否是有效 vtable 的地址。我知道这是平台,甚至可能是特定于编译器版本的,但它可以帮助我推动应用程序向前发展,并在有限的时间段内(比如说 3 年)摆脱所有空指针。

有没有办法获取应用程序中所有 vtable 的列表,或者检查指针是否指向有效的 vtable,以及指向 vtable 的实例是否继承自已知的基类?

0 投票
3 回答
12043 浏览

c++ - 用于多重虚拟继承和类型转换的虚拟表和虚拟指针

我对 vptr 和内存中对象的表示有点困惑,希望你能帮助我更好地理解这件事。

  1. 考虑B继承自A并且都定义虚函数f()。从我了解到的 B 类对象在内存中的表示形式如下所示:并且[ vptr | A | B ] 指向contains 。我也明白,将对象从to投射到除了忽略对象末尾的部分之外,什么也不做。这是真的吗?这种行为是不对的吗?我们希望该类型的对象执行method 而不是.vtblvptrB::f()BABAA::f()B::f()

  2. 系统中是否有一些vtables作为类的数量?

  3. vtable从两个或多个类继承的类的外观如何?C 的对象将如何在内存中表示?

  4. 与问题 3 相同,但具有虚拟继承。

0 投票
2 回答
4895 浏览

c++ - 一个类的对象(使用单/多继承)将有多少个 vptr?

一个对象的 clas(child) 与一个多重继承 base1 和 base2 的基类具有单继承关系,通常需要多少个 vptr。确定一个对象提供了多少个 vptr 的策略是什么,它具有一对单继承和多继承。虽然标准没有具体说明 vptrs 但我只想知道一个实现是如何实现虚拟功能的。

0 投票
3 回答
3385 浏览

c++ - 为什么我的 C++ 对象会丢失其 VPTr

在调试程序的核心转储之一时,我遇到了这样一种情况:它包含的多态对象丢失了它的 VPTr,我可以看到它指向 NULL。

当对象丢失其 VPTr 时可能会出现什么情况。

在此先感谢, Brijesh

0 投票
3 回答
10019 浏览

c++ - 虚拟调度实现细节

首先,我想明确表示我确实理解 C++ 标准中没有 vtables 和 vptrs 的概念。但是我认为几乎所有实现都以几乎相同的方式实现虚拟调度机制(如果我错了,请纠正我,但这不是主要问题)。另外,我相信我知道虚函数是如何工作的,也就是说,我总能知道哪个函数会被调用,我只需要实现细节。

假设有人问我以下问题:
“您有带有虚函数 v1、v2、v3 的基类 B 和派生类 D:B,它覆盖了函数 v1 和 v3 并添加了一个虚函数 v4。解释虚拟调度的工作原理”。

我会这样回答:
对于每个具有虚函数的类(在本例中为 B 和 D),我们都有一个单独的指向函数的指针数组,称为 vtable。
B 的 vtable 将包含

D 的 vtable 将包含

现在类 B 包含一个成员指针 vptr。D 自然地继承了它,因此也包含它。在 BB 的构造函数和析构函数中设置 vptr 指向 B 的 vtable。在DD的构​​造函数和析构函数中设置它指向D的vtable。
任何对多态类 X 的对象 x 的虚函数 f 的调用都被解释为对 x.vptr[f 在 vtables 中的位置] 的调用

问题是:
1. 我上面的描述有什么错误吗?
2. 编译器如何知道 f 在 vtable 中的位置(请详细说明)
3. 这是否意味着如果一个类有两个基数,那么它就有两个 vptr?在这种情况下发生了什么?(尝试以与我类似的方式描述,尽可能详细地描述)
4. A 在顶部 B,C 在中间,D 在底部的菱形层次结构中发生了什么?(A 是 B 和 C 的虚拟基类)

提前致谢。

0 投票
4 回答
2400 浏览

c++ - 什么时候为一个类创建 v-table?

我知道,如何实现虚函数调用解析不是 C++ 标准的一部分,也不是关于 vptr 或 v-table 的任何内容,但让我在这里问这个问题。

我听说 v-table 是编译器用来实现虚函数调用解析的常用技术。我对此的理解是,每个类、每个进程只需要一个虚拟表。

我想知道的是,什么时候为一个类创建 v-table?
是第一次在进程空间中创建给定类型的类(需要 v-table)时吗?
在该进程空间中所有其他随后创建的该类型的对象,是指已经创建的 v-table?
这个 v-table 什么时候会被删除?

如果这是太主观或讨论类型的问题,我很抱歉,但这些问题在我脑海中萦绕了一段时间,我觉得在这里问它是可以的。

0 投票
11 回答
5662 浏览

c++ - 替代的虚函数调用实现?

C++通过虚拟机制支持动态绑定。但据我了解,虚拟机制是编译器的实现细节,标准只是指定在特定场景下应该发生的行为。大多数编译器通过虚拟表和虚拟指针来实现虚拟机制。这与虚拟指针和表的实现细节无关。我的问题是:

  1. 除了虚拟指针和虚拟表机制之外,是否有任何编译器以任何其他方式实现虚拟函数的动态调度?据我所知,大多数(读G++,微软Visual Studio)都是通过虚拟表、指针机制来实现的。那么实际上还有其他编译器实现吗?
  2. sizeof任何只有一个虚函数的类都将是该编译器上一个指针(vptr inside )this大小。那么鉴于虚拟指针和 TBL 机制本身就是编译器实现,我上面的这句话会永远成立吗?
0 投票
3 回答
332 浏览

c++ - 为什么我们甚至需要 VPTR?

为什么我们不对非虚函数使用同样的方法呢?

我的意思是,为什么我们要以这种方式使用虚函数?我们不能将它们用作非虚拟的并覆盖它们吗?

如果这种方法可以节省我们的时间/空间或其他任何东西,为什么我们不对非虚拟函数使用相同的方法呢?我的意思是,对于特定的类会有一个函数表是有道理的。

无论如何,提前谢谢,我只是有点困惑。

0 投票
5 回答
6524 浏览

c++ - 了解多重继承中的vptr?

我试图理解书中有效 C++ 中的陈述。下面是多重继承的继承图。

在此处输入图像描述

在此处输入图像描述

现在这本书说 vptr 需要每个类中的单独内存。它还做出以下声明

上图中的一个奇怪之处在于,即使涉及四个类,也只有三个 vptr。实现可以随意生成四个 vptr,但三个就足够了(事实证明 B 和 D 可以共享一个 vptr),并且大多数实现都利用这个机会来减少编译器生成的开销。

我看不出为什么在每个类中都需要单独的内存用于 vptr。我知道 vptr 是从基类继承的,无论继承类型是什么。如果我们假设它显示了继承的 vptr 的结果内存结构,他们怎么能做出这样的声明

B和D可以共享一个vptr

有人可以澄清一下多重继承中的 vptr 吗?

  • 我们需要在每个类中单独的 vptr 吗?
  • 另外,如果上述情况属实,为什么 B 和 D 可以共享 vptr ?