让我们来对比一下没有虚函数的C++类和有虚函数的C++类有什么不同吧,
没有虚函数的类变量指针的类型是已知的,尽管该指针所指向的对象并不确定,但这不会影响对于类方法的定位,因为方法在代码段中,只要类型确定了,方法的地址也就确定了,这与具体对象的地址无关。这样一来,由于类变量的类型是确定的,所以在编译的时侯就可以确定类变量的方法的调用地址。
而在有虚函数的情况下情况就比较复杂了,这时为了实现多态,类变量指针可能是一个父类指针,而这个指针到底指向哪个子类对象还不知道,也就是指针的真实类型还不确定,所以也无法确定将要调用的类方法的真实地址,也就无法在编译时刻给出被调用类方法的地址,为了让这个父类指针正确的执行它指向的子类的方法,这时虚表就派上用场了,虚表存在于具体的子类对象中,用于保存虚函数的真实地址,在虚表中,各个虚函数的排列顺序是一定的,虚表在具体对象中的偏移量也是一定的,对象的地址就是虚表的地址,于是虚表地址+4h肯定是方法A的地址这个对应关系永远不会变化,而虚表中保存的方法A的地址却随着具体类型的变化而变化,这个子类方法A的地址是在对象NEW的时侯填写进去的,这样就把不同子类中变化的方法地址转化成了不变的虚表地址,在编译的时刻只要把调用地址写成这个不变的虚表地址的内容所指向的地址,就完成了对虚函数的调用。