多态性与虚函数
多态性
多态意义就是使得接口重用,不管传过来哪一个类的对象,我们都可以通过同一个接口去找到相对应的调用方法;
OOP的核心思想之一。当我们使用基类的引用或者指针去调用基类中定义的一个函数时,我们并不知道该函数真正的作用对象是基类的对象还是子类的对象。引用或指针的静态类型和动态类型不一致正是支持这一特性的根本原因。如果该类是一个虚函数,那么直到运行时才能完全确定执行那个版本,依据则是指针或者引用绑定了哪个版本的对象。
虚函数
通常用法
声明基类的指针,利用该指针去指向任意一个子类对象,调用相应的虚函数,这样可以根据子类的不同而调用不同的方法;
派生类中的虚函数
- 如果在派生类中覆盖了某个虚函数,可以再一次用virtual关键字进行声明,也可以不用,因为默认如果基类的某个函数是虚函数,则所有派生类中它都是虚函数。
- 派生类覆盖的虚函数的参数列表类型必须与基类中的函数形参类型严格匹配;
虚函数表
虚函数本质上是通过一张虚函数表实现的,每当程序声明了一个虚函数时,就会为这个类构造一张表。V表是由虚函数的地址组成的。
每当有虚函数被调用时,V表就会被用来解析函数地址。包含虚函数的类的对象实例都会包含一个虚拟指针,这个指针会在对象地址的最开始处,称为vptr,通过这个vprt就可以找到V表的内存地址。而V表又包含一个或多个虚函数的基地址。
这就可以完成虚函数调用期间的动态绑定:在运行时,首先是基类的指针被赋予派生类对象的地址,这样就可以找到所属类的虚函数表的地址,通过虚函数的名字在虚函数表中找到对应的虚函数地址,然后进行调用。
注意:虚函数表是针对类的,同一个类的多个对象都指向同一个虚函数表;