什么是虚函数?
允许派生类重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类或派生类的同名函数。
什么是纯虚函数?
基类中虚函数只有声明没有实现体。含有纯虚函数的类为抽象类,如果基类定义多个纯虚函数,子类没有一一将纯虚函数实现,那么子类依旧也会被认为是抽象类。
因为纯虚函数不能被调用,所以包含纯虚函数的类是无法实例化的,那么这时候就出现了一个抽象类,它作为多个子类的共同基类,就相当于给多个子类提供一个公共的接口,我们可以通过定义这个公共接口的指针或引用,指向派生类的某个对象,这样就可以通过它来访问派生类对象中的虚函数。
为什么析构函数经常定义为虚析构函数?
虚析构函数:只有当一个类被定义为基类的时候,才会把析构函数写成虚析构函数。
为什么一个类为基类,析构函数就需要写成虚析构?
假设现在有一个基类指针,指向派生类。此时释放基类指针,如果基类没有虚析构函数,此时只会看指针的数据类型,而不会看指针指向的数据类型,所以此时会发生内存泄露。
虚函数表是如何实现的?
先思考一个问题,编译器是在什么时候实现不同对象能调用同名函数绑定关系的?
在创建对象的时候,编译器偷偷给对象加了一个vptr指针。只要我们类中定义了虚函数,那么在实例化对象的时候,就会给对象添加一个vptr指针,类中创建的所有虚函数的地址都会放在一个虚函数表中,vptr指针就指向这个表的首地址。
对象在实例化时,先调用基类构造函数,存在虚函数,将vptr指向基类的虚函数表,调用派生类构造函数,存在虚函数,将vptr指向派生类的虚函数表。所以都只会调用自己类中的虚函数。
如果子类重写了父类的某一虚函数,那么父类的该虚函数就被隐藏,无论以后怎么调用,调用同名虚函数调用的都是子类虚函数
虚函数的效率与普通函数比较
虚函数效率低,因为通过vptr指针调用重写的函数是在程序运行时进行的,需要通过寻址操作找到该函数才能真正调用。而普通成员函数在编译时就确定了调用的函数。
子类的虚函数表中只有子类虚析构函数,那它怎样析构父类呢?
子类的析构函数中包含着对父类析构函数的调用。
多重继承时的虚函数表
https://www.cnblogs.com/findumars/p/6358207.html?utm_source=itdadao&utm_medium=referral
参考资料:
https://www.jianshu.com/p/3ed5f749b93c