强制虚拟方法表中函数的顺序?
如何控制虚拟表中虚拟函数的顺序?它们的排列顺序是否与声明的顺序相同?
当继承带有虚表的类时,继承类的虚表是基类的扩展,还是仅用继承类的虚函数创建的全新虚表。 (即虚表还在类的索引+0x0处吗?)
How can I control the order of virtual functions in the virtual table? Are they laid out in the same order that they are declared in?
When inheriting a class with a virtual table, is the virtual table of the inherited class an extension of the base class, or is an entirely new virtual table created with only the inherited classes virtual functions. (i.e. is the virtual table still at index +0x0 of the class?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
(a) 就标准而言,你不能,(事实上你甚至不能假设 vtable 存在)。 (b) 可能吧,但是什么情况下你需要控制订单,但你自己无法检查?检查的方法是查看虚拟调用的反汇编(并找到添加到 vtable 指针的偏移量以获取调用地址)或查看 vtable 本身的反汇编。
视情况而定。对于单一继承,可能是基类的扩展,每个对象的索引 0 指向该类的虚拟表,并带有指向基类中声明的每个虚拟函数的正确实现(可能是覆盖)的指针,然后是指向派生类中声明的每个虚函数的指针。对于多重继承和虚拟继承来说,事情没有(不可能)那么简单。每个对象将包含多个指针,要么指向 vtable,要么指向包含 vtable 和其他类信息的结构,并且当您围绕类层次结构进行转换时,对象的指针值会发生变化。尝试一下看看。
视
所有这一切都是为了一个非常假设的“典型实现”。编译器编写者有他们的技巧。
(a) As far as the standard is concerned, you can't, (in fact you can't even assume that vtables exist). (b) Probably, but what are the circumstances in which you need to control the order, but you can't check for yourself? The way to check is to look at the disassembly of a virtual call (and find the offset(s) added to the vtable pointer to get the call address) or to look at the disassembly of the vtable itself.
Depends. For single inheritance, probably it's an extension of the base class, and index 0 of each object points to a virtual table for the class, with pointer to the correct implementation (perhaps an override) for each virtual function declared in base classes, followed by pointers to each virtual function declared in the derived class. For multiple and virtual inheritance it isn't (can't be) that simple. Each object will contain several pointers, either to vtables or to structures which contain vtables plus other class information, and when you cast around the class hierarchy, the pointer value of the object changes. Try it and see.
All of this for a very hypothetical, "typical implementation". Compiler-writers have their tricks.
这完全是实现定义的。 C++ 标准根本没有指定任何类型的虚拟函数表——这只是它通常的实现方式。
That's completely implementation defined. The C++ standard does not specify any sort of a virtual function table at all -- that's just how it's typically implemented.
虚拟表是特定于实现的。它可以按任何顺序布置。甚至可能根本没有虚表来实现多态性。我推荐维基百科上的这篇文章,它为您的问题提供了一些答案问题。
Virtual table is implementation specific. It may be laid out in any order. Even there may be no virtual table at all to implement polymorphism. I recommend this article on Wikipedia, which gives some answers to your questions.
虽然肯定 100% 正确,但其他答案忽略了一个明显的事实。
这不是一个愚蠢的问题,具体取决于海报的目标。我们常常被迫使用特定于平台的技术来实现我们的目标。特别是,发帖者试图做的事情与 Windows 上的 COM 惊人地相似...编写可以派生的纯虚拟抽象接口是获得防弹 C++ DLL 而不需要返回到 C 接口的少数方法之一。
我在用原生 C++ 编写插件架构时遇到了同样的问题——缺乏 ABI 意味着互操作非常令人沮丧。
While certainly 100% true, the other answers ignore an obvious truth.
It's not a stupid question, depending on the posters goals. All too often, we're forced to use platform-specific technologies to achieve our goal. In particular, what the poster is trying to do is strikingly similar to COM on windows... writing pure virtual abstract interfaces that can be derived from are one of the few ways to get bulletproof C++ DLLs without dropping back down to a C interface.
I ran into the same issue while writing a plugin architecture in native C++ -- the lack of a ABI means that it is incredibly frustrating to interoperate.
您的问题真正引出的问题是您出于什么原因需要按特定顺序拥有 vtable?
这与实现相关的原因之一是编译器可能会出于性能原因或其他要求(特别是对于给定的 CPU 架构)来选择如何布局 vtable。
The question your question really begs is for what reason would you ever need to have the vtable in a particular order?
One of the reasons this is implementation dependent is because a compiler may make choices about how to layout the vtable for performance reasons, or other requirements, particular to a given CPU architecture.