目录
接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧
接上篇的多态的介绍后,接下来介绍多态的原理以及虚函数表的相关知识
一:多态的原理
1.虚函数表
这里从一道经典笔试题引入
对于这道题我们可能想到的是计算类 大小的对齐规则,结果为4,但结果为8,这是因为有虚函数的类要多考虑一指针
在32位系统下是8
如果这里再添加几个虚函数呢?
所以在这里不管类里面有多少个虚函数 ,只要是包含虚函数的类计算大小都要考虑添加一指针,再考虑对齐
但这里的一指针是什么呢?
但这里我们就看到在b1中除了_b还存有 一个_vfptr的指针在对象的前面,这个指针就叫做虚函数表指针,其中v代表virtual,f代表funcation
每一个含有虚函数的类都至少有一个虚函数表指针,他的类型为函数指针数组,而虚函数的地址是存放在虚函数表中的,虚函数表也叫虚表
2.原理分析
class Base
{
public:
virtual void Func1()
{
cout << "Func1()" << endl;
}
virtual void Func2()
{
cout << "Func2()" << endl;
}
private:
int _b = 1;
};
class Derived : public Base
{
virtual void Func1()
{
cout << "Func()" << endl;
}
private:
int _a = 0;
};
int main()
{
Base b1;
Derived d1;
return 0;
}
解释多态调用的两个条件
对于条件一:必须是父类的指针或引用来调用函数
1.父类的指针指向父类对象时,依据虚函数表指针(vfptr),在虚函数表中找到函数的地址,再call这个地址来执行接下来的操作
2.父类的指针指向子类对象时,先完成切片,找到父类的那一部分,依据虚函数表指针(vfptr),在虚函数表中找到函数的地址,再call这个地址来执行接下来的操作
3.由于经过虚函数的重写后,虚函数的地址是不相同的,所以结果是不相同的,这是就形成了多态
对于编译器来说上面的两个调用是执行的同样的操作,都只是取对象的头四个字节&#