1、在说虚函数之前先说说一个程序的内存的问题,这在我的另一个笔记中有提,
主要分:代码段,数据区,堆,栈。
C++中,代码段存放代码及常量,主要是程序中的函数包括(普通成员函数,类中的函数(虚函数、普通函数、静态成员函数))
而类的虚表中就是存放这些虚函数的地址。
类只声明的时候是不占用内存的,当声明第一个实例的时候,会生成类的函数,及以后所有的实例调用类的成员函数的时候都会调用这些函数的地址。
2、虚表:当类中含有虚函数的时候,实例化的对象在内存中的首地址就是存放一个指针,这个指针指向虚表(一段存放虚函数的连续的空间,首地址为虚函数的指针),其他实例对象也是的虚指针也是指向此地址。
当然只有一个基类的时候谈虚表是没有意义的,只有当继承的时候才能体现虚指针的强大,一个类继承其他类的时候,会继承父类的虚表,成员变量,这在子类的内存中存储方式是:子类的虚指针,父类的成员变量(多继承时按继承的顺序),自己的成员变量。
3、在子类的虚表中存在这样几种情况
(1)单一继承(不存在覆盖):子类的虚函数表中,先存放基类的虚函数,在存放子类自己的虚函数。
(2) 单一继承(存在覆盖):当子类重载了父类的虚函数,则编译器会将子类虚函数表中对应的父类的虚函数替换成子类的函数。
(3)多继承:第一个父类的虚函数、自己的虚函数、其他父类的虚函数,有覆盖则覆盖。
当对象的虚函数被调用是,编译器去查询对象的虚函数表,找到该函数,然后调用。