c++八股day2-虚函数表和虚函数表指针的创建时机

虚函数表和虚函数表指针的创建时机。

背景:用来实现多态(包括静态多态和动态多态),多态的原理就是虚函数表和虚函数表指针

虚函数表的创建时机:

a.什么时候生成的?编译器编译的时候声生成的,(前提)编译的过程中发现virtual关键字修饰的函数(当然如果有继承且基类有virtual修饰的函数,那也有自己的虚函数表指针)

b.存在哪里?可执行程序(磁盘)、运行状态(内存)

磁盘中:

.bss:未初始化的或初始化为0的全局、静态变量

.data:初始化的静态或全局变量

.rodata:(只读数据段)里面放虚函数表(虚函数地址的数组,其中地址指向text

.text:代码段

运行的时候会加载到内存,那么虚拟内存由哪几部分构成:

内核空间

栈区

文件映射区

堆区

数据区(静态存储区):.bss和.data映射到这里,.bss、.data

代码区:只读数据段(包含虚函数表)和代码段放到这里,.text、.rodata

进程的内存空间:

c++八股day2-虚函数表和虚函数表指针的创建时机_第1张图片

虚函数表指针在堆区指向虚函数表的地址,函数地址的指针又指向具体代码段的位置,那么虚函数与虚函数表指针的关系:

每个类最多只有一个虚函数表;(类中有virtual关键字修饰的时候才有且最多一个)

一个类的不同的对象(需要考虑浅拷贝和深拷贝),通常虚函数表指针不同,为了让每个对象都有自己的虚函数表指针,尽量使用深拷贝,显示的拷贝构造或重载赋值运算符(浅拷贝会共享一个虚函数表指针,深拷贝使另一个对象也有自己的虚函数表指针);

虚函数表指针就是指向虚函数表的指针

虚函数表的创建时机:

1、类对象构建的时候,把类的虚函数表地址赋值给vptr

2、如果没有构造函数的话,而类中又有虚函数表,那么编译器会生成默认的构造函数

3、继承的情况下(这是要理解多态的原理),虚函数表指针赋值过程:

a.调用基类构造函数,把A的虚函数表的地址赋值给vptr(虚拟函数表指针)

b.调用子类构造函数,把B的虚函数表的地址赋值给vptr(也就是赋值了两次)

class A{

public:

        virtual void func();

};

class B:public class A{

};

多态:A* p=new B();关键点是,指针指向哪个类型的对象

虚函数表是类中有virtual关键字声明的函数,那么这个类在编译的时候就会为它生成虚函数表,存放着虚函数的函数地址,指向代码段中具体的代码位置

你可能感兴趣的:(c++,开发语言)