目录
函数虚表
多态原理
普通调用和多态调用的区别
函数虚表
含有虚函数的类,都会有一个函数虚表指针,指向函数虚表。
class Base{public:virtual void Func1(){cout << "Func1()" << endl;}private:int _b = 1;};
_vfptr就是函数虚表指针
函数虚表中存储都是函数的地址,函数虚表就是一个函数指针数组。
vs下的虚表通常是以0000000结尾的
在base中增加个虚函数,看看会不会出现在虚表中。
class Base
{
public:virtual void Func1(){cout << "Func1()" << endl;}virtual void Func2(){cout << "Func2()" << endl;}
private:int _b = 1;
};
虚表中果然增加了Func2的地址
我们增加一个派生类Derive去继承Base Derive中重写Func1
我们发现在Derive的虚表中,func1的为位置被覆盖
多态原理
为什么不同的类执行有不同的结果呢?
class person
{
public:virtual void BuyTicket(){cout << "全价票" << endl;}
};class children : public person
{virtual void BuyTicket(){cout << "半价票" << endl;}
};void fun(person * A)
{A->BuyTicket();
}int main()
{ person wys;fun(&wys);children ymy;fun(&ymy);
}
在第一个func中,A指向wys ,A->BuyTicket 会在wys中的虚表中寻找。
在第二个func中,A指向ymy ,A->BuyTicket会在ymy中的虚表中寻找,ymy中的BuyTicket已经被重写。
这样就实现出了不同对象去完成同一行为时,展现出不同的形态。
普通调用和多态调用的区别
借助汇编代码
多态调用 普通调用
多态调用是 运行时到对象中寻找函数地址,然后调用函数。
普通调用是 在编译时已经从符号表确认了函数的地址,直接call 地址。