通过监视可以发现,基类和子类的虚表指针指向的是不同的虚表(监视窗口可以证实),而且虚表里面的函数地址也是不一样的。这就符合我们的预期了,因为多态的调用的时候,就是通过虚表指针去找到对应虚表里面的虚函数,正巧子类和基类里面的func1函数构成了多态调用,所以在运行时会调用到不同的func1,所以监视窗口里就有不同的两个func1。
以下是多继承的情况:
#include<iostream>
using namespace std;
class Base1
{
public:
virtual void func1()
{
cout << "Base1" << endl;
}
};
class Base2
{
public:
virtual void func1()
{
cout << "Base2" << endl;
}
};
class Dervied :public Base1,public Base2
{
public:
virtual void func1()
{
cout << "Dervied" << endl;
}
};
int main()
{
Dervied d;
return 0;
}
可以看到子类继承了基类的虚表指针,所以有两个指针,分别指向的是两个虚表。所以在多继承的情况下,子类可能不止包含一个虚表。
如果是这种情况,子类新增了一个虚函数:
#include<iostream>
using namespace std;
class Base1
{
public:
virtual void func1()
{
cout << "Base1" << endl;
}
};
class Base2
{
public:
virtual void func1()
{
cout << "Base2" << endl;
}
};
class Dervied :public Base1,public Base2
{
public:
virtual void func1()
{
cout << "Dervied" << endl;
}
virtual void func2()
{
cout << "Dervied2" << endl;
}
};
此时会有疑问,子类的新增函数为什么没有显示到监视窗口中,那是因为编译器自行进行了优化,省略掉了。而实际上是存在第一个继承的基类的虚表里。也就是被Base1虚表指针指向的。
PS:
子类继承了基类的虚表,并对派生类重写了的虚函数地址进行覆盖,就形成了子类独享的虚表。