C++虚函数表

看下边 一段代码:

#include

class Base
{
public:
Base(int a):ma(a){}
virtual void Show()
{
std::cout << “ma:” << ma << std::endl;
}
protected:
int ma;
};
class Derive :public Base
{
public:
Derive(int b):mb(b),Base(b){}
void Show()
{
std::cout << “mb:” << mb << std::endl;
}
protected:
int mb;
};
int main()
{
Base* pb = new Derive(10);
std::cout << sizeof(Base) << std::endl;

虚表:vftable

类和虚表的关系: 一个类中只有一张虚函数表。

虚表的组成与布局:
在这里插入图片描述

对象与虚表的关系:所有对象共享虚表。

vftable --> 数据
数据的共享,可以利用指针指向数据的内存单元从而实现数据共享
同理:虚表的共享也可以利用指针vfptr(虚函数指针)
在这里插入图片描述
vfptr与对象的位置关系:
1)指针在上,对象在下?
2)对象在上,指针在下?

结果是指针在上,对象在下;
为什么呢
因为虚函数指针vfptr的布局优先级最高
所以base基类的内存布局应该为

Base::
vfptr
ma
虚函数指针指向的虚表中的内容

在这里插入图片描述
接下来看一下派生类
由上边代码可以看出:派生类中没有虚函数,那就没有虚表?也不存在虚函数指针?
按照我们的理解,没有虚表没有虚函数指针应该是8个字节,但结果如下:
在这里插入图片描述
结果是12
这就要说到虚函数的特性了

基类中同名同参的函数是虚函数,那么派生类中同名同参也会变成虚函数;

Base类中Show()为虚函数
Derive公有继承Base类
所以,即使Derive类中没有virtual关键字,但Show()也为虚函数。既然是虚函数,也就存在虚表和虚函数指针

则派生类的布局为:
在这里插入图片描述
由上图可以看出Derive类应该占16个字节,但结果却是12 这是什么原因?
在此之前,来看一下派生类的虚表是如何生成的
在Base类中添加Print函数
在这里插入图片描述
按照我们的理解派生类的虚表如下:
在这里插入图片描述
但这样效率太低,系统会进行虚表合并
在这里插入图片描述
由上图可以看出两个虚函数指针指向同一张虚函数表,会造成资源内存浪费,所以会进行指针合并,合并时由派生类向基类进行合并。
在这里插入图片描述
所以,派生类的大小就为12个字节。

原文链接: https://www.cnblogs.com/Mllll/p/15689453.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++虚函数表

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/328376

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月1日 下午4:40
下一篇 2023年3月1日 下午4:40

相关推荐