问题标签 [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.
c++ - 是否存在类声明虚拟方法而编译器不需要使用 vptr 的情况?
我想知道是否有可能的优化,即使对象的类型是具有虚拟方法的类,编译器也不需要将 vptr 分配给实例化对象。
例如考虑:
在这个例子中,编译器在编译时肯定知道 pFoo 的类型是什么,所以它不需要为 pFoo 使用 vptr,对吧?有没有更有趣的情况,编译器可以避免使用 vptr?
c++ - 获取所有现有 vtable 的列表
在我的应用程序中,我有很多空指针(这是由于历史原因,应用程序最初是用纯 C 编写的)。在我的一个模块中,我知道 void-pointers 指向可以从已知基类继承的类的实例,但我不能 100% 确定这一点。因此,对 void 指针执行 dynamic_cast 可能会出现问题。可能,void 指针甚至指向一个普通结构(因此结构中没有 vptr)。
我想调查 void-pointer 指向的内存的前 4 个字节,看看这是否是有效 vtable 的地址。我知道这是平台,甚至可能是特定于编译器版本的,但它可以帮助我推动应用程序向前发展,并在有限的时间段内(比如说 3 年)摆脱所有空指针。
有没有办法获取应用程序中所有 vtable 的列表,或者检查指针是否指向有效的 vtable,以及指向 vtable 的实例是否继承自已知的基类?
c++ - 用于多重虚拟继承和类型转换的虚拟表和虚拟指针
我对 vptr 和内存中对象的表示有点困惑,希望你能帮助我更好地理解这件事。
考虑
B
继承自A
并且都定义虚函数f()
。从我了解到的 B 类对象在内存中的表示形式如下所示:并且[ vptr | A | B ]
指向contains 。我也明白,将对象从to投射到除了忽略对象末尾的部分之外,什么也不做。这是真的吗?这种行为是不对的吗?我们希望该类型的对象执行method 而不是.vtbl
vptr
B::f()
B
A
B
A
A::f()
B::f()
系统中是否有一些
vtables
作为类的数量?vtable
从两个或多个类继承的类的外观如何?C 的对象将如何在内存中表示?与问题 3 相同,但具有虚拟继承。
c++ - 一个类的对象(使用单/多继承)将有多少个 vptr?
一个对象的 clas(child) 与一个多重继承 base1 和 base2 的基类具有单继承关系,通常需要多少个 vptr。确定一个对象提供了多少个 vptr 的策略是什么,它具有一对单继承和多继承。虽然标准没有具体说明 vptrs 但我只想知道一个实现是如何实现虚拟功能的。
c++ - 为什么我的 C++ 对象会丢失其 VPTr
在调试程序的核心转储之一时,我遇到了这样一种情况:它包含的多态对象丢失了它的 VPTr,我可以看到它指向 NULL。
当对象丢失其 VPTr 时可能会出现什么情况。
在此先感谢, Brijesh
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 的虚拟基类)
提前致谢。
c++ - 什么时候为一个类创建 v-table?
我知道,如何实现虚函数调用解析不是 C++ 标准的一部分,也不是关于 vptr 或 v-table 的任何内容,但让我在这里问这个问题。
我听说 v-table 是编译器用来实现虚函数调用解析的常用技术。我对此的理解是,每个类、每个进程只需要一个虚拟表。
我想知道的是,什么时候为一个类创建 v-table?
是第一次在进程空间中创建给定类型的类(需要 v-table)时吗?
在该进程空间中所有其他随后创建的该类型的对象,是指已经创建的 v-table?
这个 v-table 什么时候会被删除?
如果这是太主观或讨论类型的问题,我很抱歉,但这些问题在我脑海中萦绕了一段时间,我觉得在这里问它是可以的。
c++ - 替代的虚函数调用实现?
C++通过虚拟机制支持动态绑定。但据我了解,虚拟机制是编译器的实现细节,标准只是指定在特定场景下应该发生的行为。大多数编译器通过虚拟表和虚拟指针来实现虚拟机制。这与虚拟指针和表的实现细节无关。我的问题是:
- 除了虚拟指针和虚拟表机制之外,是否有任何编译器以任何其他方式实现虚拟函数的动态调度?据我所知,大多数(读G++,微软Visual Studio)都是通过虚拟表、指针机制来实现的。那么实际上还有其他编译器实现吗?
sizeof
任何只有一个虚函数的类都将是该编译器上一个指针(vptr inside )this
的大小。那么鉴于虚拟指针和 TBL 机制本身就是编译器实现,我上面的这句话会永远成立吗?
c++ - 为什么我们甚至需要 VPTR?
为什么我们不对非虚函数使用同样的方法呢?
我的意思是,为什么我们要以这种方式使用虚函数?我们不能将它们用作非虚拟的并覆盖它们吗?
如果这种方法可以节省我们的时间/空间或其他任何东西,为什么我们不对非虚拟函数使用相同的方法呢?我的意思是,对于特定的类会有一个函数表是有道理的。
无论如何,提前谢谢,我只是有点困惑。
c++ - 了解多重继承中的vptr?
我试图理解书中有效 C++ 中的陈述。下面是多重继承的继承图。
现在这本书说 vptr 需要每个类中的单独内存。它还做出以下声明
上图中的一个奇怪之处在于,即使涉及四个类,也只有三个 vptr。实现可以随意生成四个 vptr,但三个就足够了(事实证明 B 和 D 可以共享一个 vptr),并且大多数实现都利用这个机会来减少编译器生成的开销。
我看不出为什么在每个类中都需要单独的内存用于 vptr。我知道 vptr 是从基类继承的,无论继承类型是什么。如果我们假设它显示了继承的 vptr 的结果内存结构,他们怎么能做出这样的声明
B和D可以共享一个vptr
有人可以澄清一下多重继承中的 vptr 吗?
- 我们需要在每个类中单独的 vptr 吗?
- 另外,如果上述情况属实,为什么 B 和 D 可以共享 vptr ?