加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 03:32:42 所属栏目:百科 来源:网络整理
导读:对于其clas(子)具有单继承的对象,通常需要多少个vptrs,其基类为多个继承base1和base2.确定对象提供了多少个vpt的策略是什么,它提供了几个单继承和多继承.虽然标准没有指定vptrs,但我只是想知道一个实现如何实现虚函数. 解决方法 你为什么在乎?简单的答案就
对于其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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读