虚函数

一、申明与定义方式

二、虚函数作用与应用

三、虚基表

1、虚函数表是与类关联的,也就是说,一个类只有一张虚函数表。(从这个方面上说,虚函数类似于类的静态函数)
2、VTable中虚函数的位置是由基类决定的,所以,哪怕你在派生类中不是按基类的顺序来重写虚函数,派生类的VTable中虚函数的存放顺序和基类的也是一样的。
3、虚函数指针VPtr是与对象关联的,每个对象都有一个虚函数指针,但是,同类的对象的虚函数指针的值是相同的。因为都指向该类的虚函数表。
4、虚函数指针VPtr的值是在调用构造函数时进行初始化的。如果该类没有构造函数,那么,默认构造函数干的唯一一件事就是初始化VPtr。所以,当你在写一个类的构造函数时,一定不要写一个空的默认构造函数

四、C++迟绑定实现机理(编译器都是类似于此种方式实现的):
1、为每个含有虚函数的类(基类以及派生类)都创建一张虚函数表(VTable,存储于常量区),依次存放虚函数的地址。对于派生类来说,如果没有重写其基类的虚函数,那么,将会在VTable中存放基类的虚函数地址。
2、为每个含有虚函数的类的对象,创建一个指针(VPtr),指向这个类的虚函数表(所以说,同类对象的
VPtr的值是一样的,也就是说,虚函数,在这一点上,类似于类的static函数,是所有对象共有的。)
3、通过强制转换将派生类对象的地址/引用 赋给基类指针/变量(也就是向上类型转换UpCasting)

4、然后,通过基类指针/引用对象 来调用虚函数(即:polymorphic call),就会通过此时基类对象的VPtr指针在所指向虚函数表中寻址(一般是从表头地址开始,加上一定的偏移量)找到相应的函数地址,也就是之前派生类VPtr指针指向的虚函数表的函数地址。

四、虚函数继承

五、回避虚函数的默认机制

1、应用场景

基类的版本通常完成继承层次中所有类型都要做的共同任务,而派生类中定义的版本需要执行一些与派生类本身密切相关的操作;

(1)子类重写虚函数时调用基类同名函数

例如重写CDialog的OnInitDialog()时,会在首行添加一句:CDialogEx::OnInitDialog(),用来调用基类的虚函数;(https://www.cnblogs.com/zhuluqing/p/8671009.html)

(2)直接调用虚函数

double undiscounted = baseP->Quote::net_price(42)  // 使用作用域运算符

原文地址:https://www.cnblogs.com/wllwqdeai/p/13613124.html