C++ 多态(三)拓展
案例分析
分析下面程序执行输出的结果:
#include <iostream>
using namespace std;
class A
{
public:
virtual void fun1()
{
cout << "A fun1" << endl;
}
virtual void fun2()
{
cout << "A fun2" << endl;
fun1();
}
};
class B: public A
{
public:
virtual void fun1()
{
cout << "B fun1" << endl;
}
virtual void fun2()
{
A::fun2();
cout << "B fun2" << endl;
}
};
int main()
{
B b;
b.fun2();
return 0;
}
正确结果是
A fun2
B fun1
B fun2
执行流程:
- 编译器设置两个虚表,一个用于 A 类,一个用于 B 类
- 构建 B 类对象 b
- 调用 b 对象的 fun2() 函数:程序识别到 fun2 函数是虚函数,同过 b.__vptr 来访问 B 的虚表,将 b.fun2() 解析为 B::fun2()
- 在 B::fun2() 函数中调用 A::fun2(),因为程序指定了要调用基类 A 中的 fun2() 函数,所以调用 A::fun2() 函数
- 调用 A::fun2() 函数,先输出 “A fun2”,然后调用 fun1(),程序识别到 fun1() 为虚函数,通过 __vptr 来访问虚表,注意此时虽然执行的是 A::fun2(),但类对象属于 B 类,所以 __vptr 是 B 类的虚表,fun1 被解析为 B::fun1()
- 调用 B::fun1() 输出 “B fun1”,执行完成后程序返回到 A::fun2()
- 此时 A::fun2() 函数也执行完了,返回到 B::fun2(),然后输出“B fun2”