C++多态实现原理
C++多态的实现原理,一言以蔽之:在父类中存在虚函数(virtual),如果在子类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。由于虚函数的存在,编译器实行运行时绑定的机制,如果运行时实际指向的对象类型是子类的对象,就调用子类的虚函数;如果运行时实际指向的对象类型是父类的对象,就调用父类类的函数。
1.虚函数
虚函数是在基类中被声明为virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态覆盖(Override)
2.虚函数表
编译器会为每个有虚函数的类创建一个虚函数表,该虚函数表将被该类的所有对象共享。类的每个虚成员占据虚函数表中的一行。如果类中有N个虚函数,那么其虚函数表将有N*4(x64下是N*8)的大小。
派生类的虚函数表存放重写的虚函数,当基类的指针指向派生类的对象时,调用虚函数时都会根据vptr(虚表指针)来选择虚函数,而基类的虚函数在派生类里已经被改写或者说已经不存在了,所以也就只能调用派生类的虚函数版本了.
3.虚表指针
虚表指针在类对象中,每个同类对象中都有个一个vptr,指向内存中的vtable,所有同类对象,共享一个vtable,但是每个对象都自带一个vptr指向这个vtable,否则调用虚函数的时候会找不到正确的函数入口,虚表指针是对象的第一个数据成员。
(虚表(虚表存储在数据段)的地址存放在对象的起始位置,即对象的第一个数据成员就是它的虚表指针,同时注意到,虚表指针的初始化发生在构造函数过程中。)
4.派生类的虚表中虚地址的排列顺序和基类的虚表中虚函数地址排列顺序相同。