在复习c++的过程中,重点看了虚函数的内容,以前学习的时候不求甚解,如今重新学习,才更加深刻地理解了其中缘由,所谓“温故而知新”。
首先虚函数是在某基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数。是实现动态多态的一种方法。
- 那么虚函数是如何实现动态的呢?
首先要了解虚函数是如何实现的,简单的说,虚函数是通过虚函数表来实现的。每一个含有虚函数的类,都会有一个虚函数表用来存放虚函数的地址,同时类会有一个虚表指针去指向虚函数表的首地址。
从内存分布上来看,含有虚函数的类实例化一个对象,对象的首地址就存放着虚表指针。
当基类去派生派生类的时候,派生类除了继承一些数据成员、函数外,同时也会继承虚函数表,所以说虚函数表也有继承性。
此时派生类若没有覆盖基类中的虚函数,派生类的虚函数表里的函数地址和基类中一致。反之,若派生类覆盖了基类中的某个虚函数,但是派生类虚函数表中的该函数的地址则与基类不同,多个派生类重写的情况不同,虚函数表也就不同,所以说虚函数表也有多态性。
虚函数表的继承性和多态性和虚表指针是实现动态多态动态绑定的基础。
- 那么动态绑定是如何实现的呢?
简单来说,就是通过基类指针指向派生类,访问派生类中同名覆盖成员函数。
当基类指针指向派生类的时候,实际上既可以获得派生类的虚表指针,通过虚表指针,基类既可以去调用派生类中的成员函数。如此不同的派生类的虚函数不同,调用的时候实现的效果也就不同,也就符合了多态的定义,面对同一消息的不同应答。
同时呢,虚函数还有着很多其他的问题,例如构造函数、析构函数的调用顺序,构造函数为什么不能被定义为虚函数,也不能调用虚函数;析构函数为什么要定义为虚函数;虚函数的缺点;虚函数的多重继承、菱形继承等问题,相信将这几个问题搞懂之后,就对虚函数有着较为全面的理解了。