多态
多态就是多种形态,C++的多态分为静态多态与动态多态。
静态多态就是编译器根据函数实参的类型判断出要调用哪个函数。比如函数重载和函数模板。
动态多态依靠的是虚函数表和动态绑定机制,因为是在运行时根据对象的类型在虚函数表中寻找调用函数的地址来调用相应的函数,所以称为动态多态。
本文仅介绍动态多态。
在一个类的某个函数前加上virtual关键字,这个函数就变成了虚函数,当这个类中存在虚函数时,编译器会给这个类创建一个虚函数表,虚函数表里存放了这个类中所有虚函数的地址。
也就是说,虚函数表是在编译期间就已经生成了!
class A
{
public:
A() {
}
~A() {
}
virtual void func_one() {
}
virtual void func_two() {
}
};
以上面的这个类A为例,类A里有两个虚函数func_one()、func_two()。
编译完成后,源程序会生成可执行程序(如果对这个过程不是很了解,可以看博客一个程序的一生:从源程序到可执行程序再到进程),可执行程序的格式如下,我们可以看到,类A的虚函数表里存放着各个虚函数的地址,每个地址对应着虚函数的代码实现。值得注意的是,类的非虚函数并不在虚函数表里。
然后程序开始运行了,程序运行时,上图的可执行程序的某些节会被装入内存,成为一个进程,过程如下图:

那么在我们的这个例子里,运行时类A的内存是什么样的呢?假设主函数里实例化了2个类A的对象,分别是a1、a2。
int main() {
A *a1 = new A();
A *a2 =<