#include <iostream>
#include <string>
#include <vector>
#include <cctype>
using namespace std;
//单一继承下有虚函数覆盖
//派生类只有一个虚函数表,派生类对象只有一个虚指针来指向这个虚函数表。
//虚函数表中按照基类虚函数(若派生类override基类的虚函数,则虚函数表中原先存放的基类虚函数的地址变为相应的派生的虚函数的地址)、派生类新增的虚函数顺序依次排列。
class Base
{
public:
int x;
virtual void f(){cout << "Base::f" << endl;}
virtual void g(){cout << "Base::g" << endl;}
virtual void h(){cout << "Base::h" << endl;}
};
class Derive:public Base
{
public:
int y;
virtual void f(){cout << "Derive::f" << endl;}
virtual void g(){cout << "Derive::gg" << endl;}
virtual void hh(){cout << "Derive::hh" << endl;}
};
typedef void (*Fun)();
int main()
{
Fun pFun;
Base base;
void*** p = (void***)&base;
cout<<*p<<endl; // 虚函数表的地址
cout<<(**p)<<endl; //虚函数表中指向第一个虚函数的地址
cout<<(*p)[1]<<endl;
cout<<(*p)[2]<<endl;
Derive derive;
void*** q = (void***)&derive;
cout<<*q<<endl; // 虚函数表的地址
//由于derive类override基类的第一个虚函数f();此时派生类虚函数表中的第一项的内容为指向Derive类f()函数的地址
cout<<(**q)<<endl; //虚函数表中指向第一个虚函数的地址Derive::f(){}
//cout<<(***q)<<endl; // !!!错误,提示表达式必须是指向完整类型的指针,q为void之故
//对象运行时类型识别的指针 ,存放在vptr-1处的内存中
//cout<<*((*q)-1)<<endl; //
//下面两种表示方式意义相同
//cout<<*((*q)+1)<<endl; //虚函数表中指向第2个虚函数的地址,derive类override基类的第一个虚函数g()
cout<<(*q)[1]<<endl; //指向第一个虚函数的地址Derive::g(){}
//cout<<*((*q)+2)<<endl; //虚函数表中指向第3个虚函数的地址,由于没有覆盖,指向基类的第3个虚函数Base::h()
cout<<(*q)[2]<<endl;
//cout<<*((*q)+3)<<endl; //虚函数表中指向第4个虚函数的地址;指向派生类新增的虚函数Derive::hh()
cout<<(*q)[3]<<endl;
//cout<<*((*q)+4)<<endl; //虚函数表中指向第5个虚函数的地址;由于不存在第五个虚函数,输出结果地址是空。
cout<<(*q)[4]<<endl;
pFun = (Fun)(**q);
pFun();
pFun = (Fun)((*q)[1]);
pFun();
pFun = (Fun)((*q)[2]);
pFun();
pFun = (Fun)((*q)[3]);
pFun();
system("pause");
return 0;
}