c++类的多态和虚函数表

c++类的多态和虚函数表

提要:

这是我自己创建的一个类Father类(父类)(基类):
c++类的多态和虚函数表
Son类(子类)(派生类):
c++类的多态和虚函数表

一.为什么使用多态?

因为在使用父类(基类)指针指向子类对象时调用func1方法时不是调用的子类同名的方法还是调用的是父类的方法:

不使用virtual的情况:
c++类的多态和虚函数表

二.多态的本质是什么?

我们看到的是用父类(基类)指针指向一个对象。但是我们不知道它是指向子类对象还是它这个类型的对象。

多态就是父类(基类)指针是指向子类对象的话,调用方法时会调用子类同名的方法。

三.虚函数表:

一 .我们先来看一下用类创建对象的内存分布

内存分布是编译器设置好的,我用的是vs2017编译器在项目属性C\C++的命令行中输入/d1 reportSingleClassLayout 加上类的名称重新生成在输出列表中就能看到对象的内存分布了

Father类对象的内存分布:

这是没有虚函数的Father类对象的(没有virtual):
c++类的多态和虚函数表

有虚函数的Father类:
c++类的多态和虚函数表
我们可以看到没有虚函数表是father对象占8个字节,有虚函数表的占12个字节。一个对象的内存(如果没有虚函数)只有非静态数据成员,静态数据成员存储在数据区。普通成员函数在类的里面,不占用对象的内存空间。如果有虚函数,那就在对象的内存里加了个虚函数表指针这个指针指向的是虚函数表,虚函数表不在对象的内存空间中 ,虚函数表指针占四个字节,

Son类对象的内存分布:

这是Son类对象在继承Father类对象有虚函数时的内存分布:
c++类的多态和虚函数表

我们可以看到Sun类与Father同名的函数在虚函数列表中替换了原来的father对象函数,并且在后面增加了Son类新的秀函数我们用指针访问一下Father类和Son类的虚函数表,在图中可以看到vptr指针是占四个字节,并且是对象的首址.typedef void(*func_t)(void);func_t函数指针就可以指向没有函数返回值的没有函数参数的类型

这是用指针vptr访问Father类的虚函数表:
c++类的多态和虚函数表

这是用指针vptr访问Son类的虚函数表:
c++类的多态和虚函数表

四.总结

我们可以看一下用了多态之后:在一.的那个例子:
c++类的多态和虚函数表
我们可以看一下用了多态之后:在一.的那个例子:

[外链图片转存中…(img-n7c4fiuV-1581769123861)]

我们使用多态就是为了达到这种效果。其实这是我昨天的学的,如果我不出意外的话是3天写一次博客,好的习惯是养成的,但是你需要先坚持住这个习惯。