【c++】-虚函数表与多态

本篇文章是对B站上一个课程的笔记 https://www.bilibili.com/video/BV1LK411s7ES?from=search&seid=13723858519383902190

 Question1:虚函数引入后类会发生什么变化?

对于一个空类,其sizeof值是1

对空类加入两个普通成员函数,其sizeof仍然是1(只有成员变量会占用内存空间,普通成员函数并不会占用空间)

继续加入一个虚函数,sizeof值变成了4!!

这是因为,如果类中存在虚函数,则编译器就会在类中插入一个看不见的成员变量,也就是虚函数表指针 *vptr,该成员变量占4个字节。

Question2:虚函数表的生成时机和生成原因

当一个类中有至少一个虚函数时,在编译期间,编译器会为该类生成一个虚函数表,这个虚函数表会从始至终伴随这个类,经过编译链接保存到可执行文件中。

Question3:虚函数表与虚函数表指针的关系

 对有虚函数的类,编译器会在编译期间,在该类的构造函数中默默添加一个为虚函数表指针赋值的语句。在创建对象时,会调用构造函数,此时就会使得虚函数指针指向虚函数表。

Question4:类对象在内存中的布局

在类A中有两个普通的成员函数,两个普通虚函数,一个虚析构函数,和两个成员变量。

当生成类A对象时,在内存中的布局如下: 占用内存空间的只有虚函数表指针以及两个成员变量,虚函数表指针指向虚函数表,由于该类有三个虚函数,所以虚函数表中的三个地址分别指向三个虚函数,两个普通成员函数属于类的成员,但是不在类的对象中占有内存。

Question5:虚函数的工作原理和多态性的实现

多态必须存在虚函数,没有虚函数绝不可能存在多态。

 实现多态必须有以下三个条件

1.程序中有父类和子类的继承关系,父类指针必须含有虚函数,子类中也必须重写父类中的虚函数。

2.用父类的指针指向子类的对象/用父类的引用绑定子类的对象。

3.用这个父类指着调用子类中重写的虚函数。

该类中有一个父类Base,一个子类Derive,子类中重写了g函数,内存结构如下图所示:

父类和子类都有一个自己的虚函数表指针,指向自己的虚函数表。父类和子类的虚函数表中都有三个地址,对于普通的成员函数,虚函数表中的地址项相同,对于重写的虚函数会用新的函数地址进行覆盖。因此在用父类的指针指向子类对象时,是通过子类对象的虚函数表指针找到子类的虚函数表,从而查询到虚函数的地址。

猜你喜欢

转载自blog.csdn.net/qq_39328436/article/details/113372123