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

c++ - 非多态类型上的 Dynamic_cast

我可以理解为什么 dynamic_cast 在这种情况下确实有效:

但是为什么如果你从 B 中删除多态性它仍然有效:

是不是因为 dynamic_cast 必须只知道你给的对象的真实类型有一个参数(就像dynamic_cast<void*>/ typeid 会做的那样),而在它知道真实类型之后,它才知道该类型是否是从非多态基派生的?

0 投票
1 回答
355 浏览

c++ - 了解虚拟继承类 vtables 和 vptr 创建

下面的代码是多重继承的,每个类都有一个成员变量、一个普通函数和一个虚函数。

程序的输出如下:

看到 gdb 中的每个对象,我在下面看到:

我们看到,在基类“basec”和每个虚拟派生类“derivedc”和“derived”对象中,为它们的 vtables 添加了一个 vptr。

问题是为什么子类尽管有一个虚函数却没有它自己的 vtable,为什么它的对象中没有它自己的 vptr?子类的虚函数会出现在哪个类的vtable中?

0 投票
3 回答
97 浏览

c++ - 使用基类引用而不是指针时意外的虚函数调度

假设我有一个简单的类层次结构,如下所示,带有一个通用 api:

当我使用基类指针时,我得到正确的调度如下:

哪个正确打印:

但是,当我使用基类引用时,行为出乎意料:

打印:

为什么使用引用而不是指针时调度不同?

0 投票
1 回答
349 浏览

c++ - 派生类的新位置

C++ 大师。需要你的帮助来处理这个小挠头:

代码非常简单:在堆栈上有一个基础对象,将派生对象放入其中(是的,eeew,但请耐心等待)并调用虚拟方法,期望打印派生的输出。

实际输出

上面的代码产生以下输出:

在我尝试过的 MSVC、gcc、clang 和一些在线编译器上普遍观察到这种行为(这非常强烈地表明是我错了)。

第1部分

Placement-new 将派生类型对象重新更新到基本类型内存中。这会更新 vptr 以指向派生类型的 vtable(直接在调试器中观察到)。

主要问题:这是预期的行为吗?(我想说“是”,所以如果不是 - 请向我解释)

我想相信执行新放置(假设派生类型对象有足够的内存)应该就地初始化派生类型的全新对象。


如果我的理解是正确的,那么第一个b.talk()应该输出"Duh",因为现在的对象是派生类型的。为什么还在打印"Be-e-e"

将派生类型对象分配给基类型对象(除了导致对象拼接之外)不会复制 vptr,因此"Be-e-e"当我们到达代码。

第2部分

为什么任务中有~D()电话b = D{};?难道它不是一个临时的,应该被复制省略而不需要对该临时的析构函数调用吗?

第 3 部分

最后一个使用指针的代码块“按预期”工作,只是在这里进行完整性检查

0 投票
2 回答
276 浏览

c++ - 虚拟表和对象切片

在对象切片中,当派生类对象被复制到基类对象时,派生类的 _vptr 是否也像 Base 类的其他成员一样被复制到基类的 _vptr?如果不是,为什么?

我观察到上述代码段的以下结果。

0 投票
2 回答
197 浏览

c++ - 为什么 sizeof(Base) 与 sizeof(Derived) 没有区别

我认为sizeof(Base)应该是 12。为什么是 16?

没有虚函数,我得到 4 和 8。

预期结果:12,16

实际结果:16,16

0 投票
2 回答
282 浏览

c++ - 如果派生类还具有基类中不存在的虚函数,则创建的 vptr 数

我想知道是否为解析虚函数创建了两个“vptr”,一个在“基”类中,它将在 func1() 的派生类对象中继承,另一个在 func2() 的“派生”对象中。

0 投票
1 回答
505 浏览

c++ - 在 C++ 中更改对象的动态类型

在以下问题中,其中一个答案表明对象的动态类型不能改变:被引用对象的动态类型何时可以改变?

但是,我从 CPPCon 或其他会议的一些演讲者那里听说这不是真的。

事实上,这似乎并不正确,因为 GCC 和 Clang 在以下示例的每次循环迭代中都会重新读取 vtable 指针:

https://godbolt.org/z/MA1v8I

但是,如果添加以下内容:

然后函数g被简化为return 10;,这确实是预期的,因为final. 它还表明,动态可能发生变化的唯一可能的地方是内部GetVal

我知道重新阅读 vtable 指针很便宜,并且主要是因为纯粹的兴趣而询问。是什么禁用了这种编译器优化?

0 投票
1 回答
86 浏览

c++ - vptr 和 vtable 在下面的虚拟相关代码中是如何工作的?

据我所知,当我们在基类中创建一个虚拟函数时,编译器会创建一个可以称为 vptr 的指针,以及一个包含虚拟函数条目的 vtable,这些条目是此类的最新版本,以防被覆盖函数。并且vptr 指向 vtable。从基类派生的类具有相同的故事,它们有一个指针 vptr 和自己的 vtable,它保存最新的虚函数的条目。要理解我的问题,请按照代码

在上面的代码中,语句 p->display(); 对象 p 点调用这个类的 vptr 并从 vtable 中查找显示函数并绑定它是有道理的。但我不明白我将如何描述语句 p->base::display(); 在vptr和vtable方面。编译器如何绑定基类版本的显示功能。因为派生类的vtable中不会有基类版本的显示功能。如果我知道这里有什么不对的地方,请告诉我什么是对的。如果我是对的,那么告诉我如何描述 p->base::display(); 具有我描述的逻辑的语句 p->display(); 陈述

0 投票
2 回答
313 浏览

c++ - vptr 和 vtable 是从基类继承的吗?

可以看出,在继承链的中间D3引入了一个新的虚函数。@function3()我想知道发生这种情况时 *--vptr 和 vtable 会发生什么。D3 现在是“一种”新的基类,

https://imgur.com/a/sxFzrKG

但是当我看到 vtable 条目时,我能看到的是function1(), function2(). 我认为条目必须是function2(), function3()。为什么我不能得到我的想法?