gpt4 book ai didi

c++ - 类的对象(使用单/多继承)有多少个 vptr?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:22:52 27 4
gpt4 key购买 nike

一个对象通常需要多少个 vptr,其 clas(child) 具有单一继承,基类多重继承 base1 和 base2。识别一个对象有多少个 vptr 的策略是什么,它具有一对单继承和多继承。虽然标准没有具体说明 vptrs 但我只想知道一个实现是如何实现虚函数的。

最佳答案

你为什么关心?简单的答案是足够,但我猜你想要更完整的东西。

这不是标准的一部分,所以任何实现都可以随心所欲,但一般的经验法则是,在使用虚拟表指针的实现中,作为第零近似值,用于您需要的动态调度至多指向虚拟表的指针与向层次结构中添加新虚拟方法的类一样多。 (在某些情况下,可以扩展虚拟表,基类型和派生类型共享一个 vptr)

    // some examples:
struct a { void foo(); }; // no need for virtual table
struct b : a { virtual foo1(); }; // need vtable, and vptr
struct c : b { void bar(); }; // no extra virtual table, 1 vptr (b) suffices
struct d : b { virtual bar(); }; // 1 vtable, d extends b's vtable

struct e : d, b {}; // 2 vptr, 1 for the d and 1 for b
struct f : virtual b {}; // 1 vptr, f reuse b's vptr to locate subobject b
struct g : virtual b {}; // 1 vptr, g reuse b's vptr to locate subobject b
struct h : f, g {}; // 2 vptr, 1 for f, 1 for g
// h can locate subobject b using f's vptr

基本上,需要自己的动态分配(不能直接重用父对象)的类型的每个子对象都需要自己的虚拟表和 vptr。

实际上,编译器会将不同的 vtable 合并到一个 vtable 中。当 db 中的函数集上添加一个新的虚函数时,编译器会将可能的两个表合并为一个表,方法是将新槽附加到vtable,所以 d 的 vtable 将是 b 的 vtable 的扩展版本,在末尾有额外的元素以保持二进制兼容性(即 d vtable 可以解释为 b vtable 以访问 b 中可用的方法),d 对象将有一个 vptr.

在多重继承的情况下,事情变得有点复杂,因为每个基都需要与完整对象的子对象具有相同的布局,而不是单独的对象,因此会有额外的 vptrs 指向不同的区域完整对象的 vtable。

最后,在虚拟继承的情况下,事情变得更加复杂,同一个完整对象可能有多个 vtables,随着构建/破坏的发展,vptr 被更新(vptr 总是随着构建/破坏的发展而更新,但没有虚拟继承 vptr 将指向基础的 vtables,而在虚拟继承的情况下,同一类型将有多个 vtables)

关于c++ - 类的对象(使用单/多继承)有多少个 vptr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3342035/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com