多态是通过调用对象自己的虚函数表中的虚函数指针找到对应的虚函数,这样不同对象完成同一行为,展现不同状态
#include <iostream> using namespace std; class Base1{ public: virtual void Func1(){ cout << "Base1::Func1()" << endl; } virtual void Func2(){ cout << "Base1::Func2()" << endl; } void Func3(){ cout << "Base1::Func3()" << endl; } private: int _base1 = 1; }; class Base2{ public: virtual void Func1(){ cout << "Base2::Func1()" << endl; } virtual void Func2(){ cout << "Base2::Func2()" << endl; } private: int _base2 = 2; }; //单继承 class Derive1 : public Base1{ public: virtual void Func1(){ cout << "Derive1::Func1()" << endl; } virtual void Func4(){ cout << "Derive1::Func4()" << endl; } private: int _derive2 = 4; }; //多继承 class Derive2 : public Base1, public Base2{ public: virtual void Func1(){ cout << "Derive2::Func1()" << endl; } virtual void Func4(){ cout << "Derive2::Func4()" << endl; } private: int _derive2 = 4; }; //遍历虚函数表中的虚函数指针 typedef void(*VFPTR)(); void PrintVfptr(VFPTR vfptr[]){ cout << "虚表地址" << vfptr << endl; for (int i = 0; vfptr[i] != nullptr; ++i){ printf("第%d个函数地址:0X%x,->", i, vfptr[i]); VFPTR f = vfptr[i]; f(); } cout << endl; } int main(){ Base1 b1; Derive1 d1; Derive2 d2; cout << "基类虚函数表:" << endl; VFPTR* vfptr1 = (VFPTR*)(*(int*)&b1); PrintVfptr(vfptr1); cout << "单继承继承基类虚函数表:" << endl; VFPTR* vfptr2 = (VFPTR*)(*(int*)&d1); PrintVfptr(vfptr2); cout << "多继承第一继承基类虚函数表:" << endl; VFPTR* vfptr3 = (VFPTR*)(*(int*)&d2); PrintVfptr(vfptr3); cout << "多继承第二继承基类虚函数表:" << endl; VFPTR* vfptr4 = (VFPTR*)(*(int*)((char*)&d2 + sizeof(Base1))); PrintVfptr(vfptr4); return 0; }基类虚函数表
存在虚函数的类中除成员外,还多了一个_vfptr虚函数表指针在前面(也可在后面,跟平台有关)对象存放虚表指针,虚表指针指向虚函数表也称虚表,虚函数表存放虚函数指针虚函数表本质是一个存虚函数指针的指针数组,这个数组最后面访了一个nullptr虚函数表在VS下存在数据段中单继承虚函数表
派生类对象由基类继承下来的成员包括虚表指针和自己的成员两部分组成Func1完成了重写,Func2继承下来是虚函数放进虚表,Func3也继承下来,但是不是虚函数,所以不会放进虚表,编译器窗口隐藏了未重写的虚函数Func4多继承虚函数表
多继承派生类的未重写虚函数放在第一个继承基类部分的虚函数表中
