微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

对于其clas(子)具有单继承的对象,通常需要多少个vptrs,其基类为多个继承base1和base2.确定对象提供了多少个vpt的策略是什么,它提供了几个单继承和多继承.虽然标准没有指定vptrs,但我只是想知道一个实现如何实现虚函数.

解决方法

你为什么在乎?简单的答案就足够了,但我想你想要更完整的东西.

这不是标准的一部分,因此任何实现都可以按照自己的意愿自由进行,但一般的经验法则是在使用虚拟表指针的实现中,作为第0个近似值,用于动态调度,最多需要许多指向虚拟表的指针,因为有些类将新的虚方法添加到层次结构中. (在某些情况下,可以扩展虚拟表,并且基本和派生类型共享一个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(); };    // extra vtable,need b.vptr and d.vptr

struct e : d,b {};                 // 3 vptr,2 for the d subobject and one for
                                    // the additional b
struct f : virtual b {};
struct g : virtual b {};
struct h : f,g {};                 // single vptr,only b needs vtable and
                                    // there is a single b

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

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

在多重继承的情况下,事情变得有点复杂,因为每个基础需要与完整对象的子对象具有相同的布局,而不是它是单独的对象,因此将有额外的vptrs指向完整对象中的不同区域虚函数表.

最后,在虚拟继承的情况下,事情变得更加复杂,并且可能有多个vtable用于同一个完整对象,随着构造/破坏的发展,vptr会被更新(vptr总是在构造/破坏演变时更新,但没有虚拟继承vptr将指向base的vtable,而在虚拟继承的情况下,将有多个相同类型的vtable)

原文地址:https://www.jb51.cc/c/111182.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐