我从这里(2.6.2)中读到了VTT的结构。但是,我不理解所有这些内容的目的。
主虚拟指针应该指向D的主虚拟表(在vtable组中,对吗?)
辅助包含在构造直接非虚拟基类(让我们称之为B)时提供的VTT。我的理解是,由于这些直接基类( B )可能继承自虚拟类,这些直接基类(B)应该给这些已经初始化的虚拟类一些其他vtable,以“使它们相信”它们只是每个B的一部分。
现在,最后两种类型的条目的目的是什么:辅助虚拟指针和虚拟VTTs?我知道继承层次结构中的虚拟类没有被赋予一个正确的最终vtable,所以这可能是目的之一。另外,虚拟类可以从其他虚拟类继承自身(考虑V1继承自V2)。然后,V2再次需要一个特殊的vtable来“使它相信”它是V1的一部分(当V1正在构建时)。
如果您能解释VTT中每种类型条目的确切内容和用途,我将不胜感激。
发布于 2017-06-09 12:51:02
Liskov可替代性意味着派生类必须在基类可以接受的地方可用。在C++中,这意味着您可以将Derived对象的地址传递给接受Base*的函数。
现在,在复杂对象的构造过程中,您可能会遇到这样的情况:根据*this规则,C++是这样一个派生对象(因为Derived ctor已经成功运行),因此您必须能够将*this传递给一个需要Base*的函数。
但是对于多重和虚拟继承,您需要额外的预防措施。Base*必须指向Base子对象.在Itanium ABI中,这个基子对象必须有一个vtable指针来正确地描述部分构造的对象的行为。这种行为完全取决于哪些部分是构造的,哪些部分不是构造的。
虽然可以部分构造对象,但它的粒度只是类级别。被调用最多的派生构造函数确定将运行哪些基类构造函数(这是,而不是依赖于运行时行为的)。其中的每一个要么已经运行,要么没有。
因此,一个可行的实现是在每个基类下有一组vtable和一组vtable指针(可能是重叠的),并在每个构造函数成功完成时设置vtable指针。
虚拟基类与虚拟函数没有明显的关系,但是可以在vtable中存储虚拟基类偏移量,从而获得了它们的名称。当您将Derived* this传递给接受Base*的函数时,需要使用此偏移量,其中Base类型是Derived的虚拟基类。(如果是常规基类,则使用固定偏移量,该偏移量甚至可能为零)
https://stackoverflow.com/questions/44453057
复制相似问题