强制虚函数表中函数的顺序?

5
  1. 我怎样才能控制虚函数表中虚函数的顺序?它们是按照声明顺序排列的吗?

  2. 当继承带有虚函数表的类时,被继承类的虚函数表是基类的扩展,还是仅包含被继承类的虚函数的全新虚函数表被创建?(例如,虚函数表仍然位于类的index+0x0位置吗?)


1
你需要这个东西是为了做什么? - sth
7
实施。依赖的。 - Steve Jessop
我只是想学习。依赖于什么? - Sam Blackburn
1
“实现相关”意味着特定方面未在规范中定义,其细节取决于实现。 因此,它可能会因使用的编译器(GNU、Microsoft等)而改变。 - Michael Ekstrand
1
迈克尔所说的。标准只是定义了在虚函数调用时执行哪个版本的函数。由编译器编写者来确定如何实现并优化所需的行为。因此,不同的C++实现将对此和其他依赖于实现的区域有不同的细节。有时出于影响性能或其他可衡量结果的良好原因,但有时出于相当任意的原因,这只是编译器中已经完成的方式。 - Steve Jessop
5个回答

8

这完全是实现定义。C++标准没有指定任何虚函数表的结构——那只是一般情况下的实现方式。


8
  1. (a) 就标准而言,你不能做到这一点(实际上你甚至不能假设存在虚函数表)。(b) 可能是这样,但在哪些情况下需要控制顺序,却无法自己检查呢?检查的方法是查看虚函数调用的汇编代码(并查找添加到虚函数表指针以获取调用地址的偏移量),或查看虚函数表本身的汇编代码。
  2. 取决于情况。对于单继承,可能是基类的扩展,每个对象的索引0指向一个虚函数表,其中包含指向在基类中声明的每个虚函数的正确实现(可能是重写)的指针,后跟指向派生类中声明的每个虚函数的指针。对于多重和虚拟继承,情况并非如此简单。每个对象将包含几个指针,指向虚函数表或结构体,其中包含虚函数表加上其他类信息,当您在类层次结构中进行强制类型转换时,对象的指针值会发生变化。试试看。

所有这些都只是假想的“典型实现”。编译器编写者有他们的技巧。


2
虽然其他答案肯定是正确的,但它们忽略了一个明显的真相。
这不是一个愚蠢的问题,取决于发帖人的目标。我们经常被迫使用特定于平台的技术来实现我们的目标。特别是,发帖人试图做的事情与Windows上的COM非常相似...编写可以派生的纯虚抽象接口是获得强壮的C++ DLL的少数方法之一,而不会回退到C接口。
在本机C ++中编写插件体系结构时,我遇到了同样的问题——缺乏ABI意味着互操作非常令人沮丧。

2

虚表是实现特定的。它可以以任何顺序布置。甚至可能根本没有虚表来实现多态性。我建议您参考维基百科上的这篇文章,它可以回答您的一些问题。


0
你的问题实际上是想知道为什么需要以特定顺序拥有 vtable。
其中一个原因是这要依赖于具体的实现,因为编译器可能会根据特定的 CPU 架构进行性能或其他需求方面的选择来布局 vtable。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接