问题标签 [vtable]

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 投票
1 回答
1247 浏览

c++ - 抽象类(Qt)的“未定义的vtable引用”

我正在编写一个用于将表达式解析为树结构的库,并且我有一个抽象类型QCExpressionNode作为我的基类。它看起来像这样:

当我编译一些适用于子类(、、、等)的测试(QtCreator 中的另一个项目QCConstantNodeQCVariableNodeQCBinaryOperatorNode,链接器给了我一个 QCExpressionNode 的“未定义的 vtable 引用”错误。我究竟做错了什么?

0 投票
2 回答
10443 浏览

c++ - 对 vtable 的未定义引用

我有一个类afporoills可以帮助在我们的内存管理模块中查找数据。(不要问为什么这么奇怪的名字我不知道)

我不断得到

[链接器错误] 未定义对 `vtable for afporoills` 的引用

但我不知道什么是 vtable !!!我还没用过,为什么会有错误呢?

请帮助我,因为如果我不摆脱该错误,我将无法继续编写该课程。

我还需要做什么才能使test方法图灵完备?

0 投票
4 回答
834 浏览

c++ - VTable 和多态性

在阅读了很多关于 VTables 的内容后,我仍然有一个未解决的问题。

给定下一节课:

和以下测试:

我得到这个输出:

我的问题是:我知道 s 如何寻址 Circle::draw,但是 s 怎么知道变量 b=5?正如该测试所示, s 没有此信息。我在这里想念什么?

谢谢!

好了朋友们。感谢您的快速回答...

我从您的回答中了解到 Circle::draw() (*this) 的类型是 Circle。好的。我现在的问题变成了这样:因为我只希望s是 Shape* 类型,也就是说,我在我的程序中只需要 Shape 质量。编译器会以某种方式获取接下来的 4 个字节(Circle 中的b变量)吗?如果是这样,显然 Circle::draw() 将无法按预期工作..

如果不是,编译器如何知道在 s 的“结束”之后我需要接下来的 4 个字节?

0 投票
2 回答
1651 浏览

c++ - SEGFAULT - 在 C++ 纯虚拟上。为什么?

我通过 C 代码传递一个纯虚拟基类指针作为void *.

当我在 C++ 中取消引用基类时,调试器能够访问它的所有成员。但是,当我尝试访问纯虚函数时,它会出现 SEGFAULTs/Access Violation。“无法在 0xc 访问内存”调试器说(当我尝试访问纯虚函数时)。

可能在构造函数返回之前调用了函数,这有关系吗?我还应该寻找什么?所有其他变量似乎都完好无损。

代码:

更新:代码部分工作,我怀疑该对象被删除。因为它运行读处理程序(它可以删除自己),然后它运行写处理程序而不检查......所以它可能就是这样。


回答

最后更新:我想澄清一下基思的评论是正确的。我正在删除一个对象并在它被删除后尝试访问它。很简单的错误!delete this;是一个棘手的陷阱。感谢所有的评论。

0 投票
3 回答
2990 浏览

c++ - 检测特定虚函数的 vtable 偏移量(使用 Visual C++)

可以检查特定虚函数的 vtable 偏移量吗?

为什么?我希望能够检测到无意的二进制兼容性中断(请参阅http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B了解我所说的二进制兼容性)。

我知道“/d1reportSingleClassLayout”的未记录和不受支持的技术(http://blogs.msdn.com/b/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual- c-and-fixing-lnk2022.aspx),我打算使用这种技术,但如果可能的话,我还想使用一些简单的编译时间或运行时间检查。

0 投票
3 回答
2495 浏览

c++ - 虚函数调用分段错误

每当我尝试访问虚拟功能时,都会遇到分段错误。代码基本上是这样的:

我几乎尝试了我所知道的关于虚函数的一切,但它不起作用。它实际上是一个更大程序的一部分,所以它可能在那里有一些问题,但是一旦我删除虚拟功能或停止使其成为虚拟它就可以工作。有任何想法吗?

还有什么工具或方法可以检查 vtable 吗?

0 投票
4 回答
1778 浏览

c++ - C++ 复制构造函数 - 小但重要的区别

我无法弄清楚这里发生了什么,认为这很奇怪,在理解了原因后,我认为分享答案对某人的时间很有价值。

所以给出这个简单的代码:

为什么以下两个测试给出了两个不同的答案:

好吧,因为我刚刚开始了解虚拟机制,所以我认为这两个测试都会产生相同的结果(打印 Circle)。虽然这是在test2中发生的情况,但在test1 中并非如此。

为了理解原因,我写了幕后真正发生的事情。

Test1: 1. 程序执行“ Circle() ”行。1.1 调用Shape的默认构造函数(因为Circle是从Shape派生的)。1.2 调用了 Circle 的默认构造函数。

  1. 程序执行“ Shape shape = ”动作。这实际上调用了 Shape 的复制构造函数。*这里你应该注意,复制构造函数不会复制 _vptr ,它是 Circle 中的一个不可见字段。它只复制 a 的值并返回 (*this)。这是它不打印 Circle 的真正原因。

在这里,我确实有另一个问题。当运行 test1 我得到这个输出: Default Shape constructor Default Circle constructor Shape copy constructor Circle disstructor Shape distructor Print Shape the number is 8 Shape distructor

如果复制构造函数签名是Shape(const Shape& s),根据此输出,在实际将形状创建为Shape之前调用复制构造函数。这怎么可能发生?

Test2: 1. 一个新的类 Circle 实例正在堆上构建。(执行new Circle行) 2. 返回指向堆上内存中该地址的指针并放置在指针形状中。在该地址的前四个字节中是指向 Circle 虚拟表的指针。这就是为什么 test1 与 test2 不同的原因。

重要的是要理解测试之间的差异与 test1 在堆栈上构建一个 Circle 而 test2 在堆上构建一个 Circle 的事实无关。好吧,实际上它与它有关。但真正的原因是复制构造函数没有复制_vptr。

0 投票
3 回答
251 浏览

c++ - 如果有虚方法,会创建 vtable 吗?

如果我像这样创建一个非常简单的类:

(没有虚拟析构函数)编译器会创建 vtable 吗?或者现代编译器是否足够聪明以识别这种情况(这可能是错误的复制和粘贴)并且不为此类类添加虚拟表?

0 投票
4 回答
297 浏览

c++ - 处理多重继承时如何对齐指针?

假设我们有一个具体类 A 和一个抽象类 B。

考虑一个具体的 C,它继承自 A 和 B,并实现了 B:

现在我定义一个签名的函数void foo(B* b);

这是我的代码,我可以假设每个指向 B 的指针都是 A 和 B。在 foo 的定义中,如何获取指向 A 的指针?一个讨厌但有效的技巧是像这样对齐反向指针:

请记住,C 没有超类型,实际上,有许多类似于 C 的类,只有 A 和 B。请随意质疑我的逻辑和这个设计示例,但问题仅与指针对齐有关.

0 投票
5 回答
6524 浏览

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

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

在此处输入图像描述

在此处输入图像描述

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

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

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

B和D可以共享一个vptr

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

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