虚函数的实现:
- 关键字:虚函数表,虚函数表的指针。
(1)一个类会产生一堆指向虚函数的指针,这些指针被统一的放在一个数组里面,这个数组也叫虚函数表(又叫vtbl)
(2)每实例化一个对象,系统内部会添加一个虚函数表的指针(又叫vptr),通常放在这个类中内存的最前面。
(3)每个有虚函数的类都有自己的虚函数表,没有虚函数这个类就没有虚函数表。(4)如果父类有一个虚函数A,子类override虚函数A,那么这个方法将被覆盖。
在子类转成父类的时候,再调用虚函数A,会执行子类的虚函数A
当虚函数遇上继承
(参考:C++ 虚函数表解析_haoel的博客-CSDN博客_虚函数表)
分四种情况:
- 子类继承带有虚函数的父类(无虚函数覆盖:子类不override父类的虚方法)
Derived d; //定义一个子类。
(1)Derived类继承Base类,其中各自的f(), g(), h(), f1(); g2(); h1();均为虚函数,虚函数在虚函数表的内存分布如下。
(2)函数在虚函数表中先后顺序是由声明顺序决定的。
- 子类继承带有虚函数的父类(有虚函数覆盖:子类override父类的虚方法)
(1)Derived d; //定义一个子类。
(2)子类overide父类的f()方法,于是父类的f()方法被覆盖。所以可见Base::f()的函数被 Derived::f()方法覆盖。
(3)调用实现多态
Base* tmp = &d; // 子类转父类,多态
tmp->f(); //执行的是Derived::f()方法,而不是Base::f()
- 子类继承多个父类(无虚函数覆盖:子类不会overide父类的虚方法)
class Derived : public Base1, public Base2, public Base3 { ... }
Derived d;
(1)可见每个父类都有自己的虚函数表
(2)放在第一个的Base1是因为第一个被继承
- 子类继承多个父类(有虚函数覆盖:子类会overide父类的虚方法)
class Derived : public Base1, public Base2, public Base3 { ... }
Derived d; // Derived类overide父类的f()方法 Base1 *b1 = &d; Base2 *b2 = &d; Base3 *b3 = &d; b1->f(); //Derive::f() b2->f(); //Derive::f() b3->f(); //Derive::f()
然后把子类转成任意一种父类都会调用override的方法。实现了多态!!