问题标签 [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++ - 非多态类型上的 Dynamic_cast
我可以理解为什么 dynamic_cast 在这种情况下确实有效:
但是为什么如果你从 B 中删除多态性它仍然有效:
是不是因为 dynamic_cast 必须只知道你给的对象的真实类型有一个参数(就像dynamic_cast<void*>
/ typeid 会做的那样),而在它知道真实类型之后,它才知道该类型是否是从非多态基派生的?
c++ - 了解虚拟继承类 vtables 和 vptr 创建
下面的代码是多重继承的,每个类都有一个成员变量、一个普通函数和一个虚函数。
程序的输出如下:
看到 gdb 中的每个对象,我在下面看到:
我们看到,在基类“basec”和每个虚拟派生类“derivedc”和“derived”对象中,为它们的 vtables 添加了一个 vptr。
问题是为什么子类尽管有一个虚函数却没有它自己的 vtable,为什么它的对象中没有它自己的 vptr?子类的虚函数会出现在哪个类的vtable中?
c++ - 使用基类引用而不是指针时意外的虚函数调度
假设我有一个简单的类层次结构,如下所示,带有一个通用 api:
当我使用基类指针时,我得到正确的调度如下:
哪个正确打印:
但是,当我使用基类引用时,行为出乎意料:
打印:
为什么使用引用而不是指针时调度不同?
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 部分
最后一个使用指针的代码块“按预期”工作,只是在这里进行完整性检查
c++ - 虚拟表和对象切片
在对象切片中,当派生类对象被复制到基类对象时,派生类的 _vptr 是否也像 Base 类的其他成员一样被复制到基类的 _vptr?如果不是,为什么?
我观察到上述代码段的以下结果。
c++ - 为什么 sizeof(Base) 与 sizeof(Derived) 没有区别
我认为sizeof(Base)
应该是 12。为什么是 16?
没有虚函数,我得到 4 和 8。
预期结果:12,16
实际结果:16,16
c++ - 如果派生类还具有基类中不存在的虚函数,则创建的 vptr 数
我想知道是否为解析虚函数创建了两个“vptr”,一个在“基”类中,它将在 func1() 的派生类对象中继承,另一个在 func2() 的“派生”对象中。
c++ - 在 C++ 中更改对象的动态类型
在以下问题中,其中一个答案表明对象的动态类型不能改变:被引用对象的动态类型何时可以改变?
但是,我从 CPPCon 或其他会议的一些演讲者那里听说这不是真的。
事实上,这似乎并不正确,因为 GCC 和 Clang 在以下示例的每次循环迭代中都会重新读取 vtable 指针:
但是,如果添加以下内容:
然后函数g
被简化为return 10;
,这确实是预期的,因为final
. 它还表明,动态可能发生变化的唯一可能的地方是内部GetVal
。
我知道重新阅读 vtable 指针很便宜,并且主要是因为纯粹的兴趣而询问。是什么禁用了这种编译器优化?
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(); 陈述
c++ - vptr 和 vtable 是从基类继承的吗?
可以看出,在继承链的中间D3
引入了一个新的虚函数。@function3()
我想知道发生这种情况时 *--vptr 和 vtable 会发生什么。D3 现在是“一种”新的基类,
但是当我看到 vtable 条目时,我能看到的是function1()
, function2()
. 我认为条目必须是function2()
, function3()
。为什么我不能得到我的想法?