#include <iostream>
#include <string>
#include <vector>
#include <cctype>
using namespace std;
//单一继承下无虚函数覆盖
//派生类只有一个虚函数表,派生类对象只有一个虚指针来指向这个虚函数表。虚函数表中按照基类虚函数、派生类新增的虚函数顺序依次排列。
//直接使用三级指针,第二次解引用时可以直接访问到虚函数地址。不需要像前面博客中一步步的类型转换。
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 ff(){cout << "Derive::ff" << endl;}
virtual void gg(){cout << "Derive::gg" << endl;}
virtual void hh(){cout << "Derive::hh" << endl;}
};
typedef void (*Fun)();
int main()
{
Fun pFun;
Derive derive;
void*** q = (void***)&derive;
cout<<q<<endl;
cout<<*q<<endl; // 虚函数表的地址
cout<<(**q)<<endl; //虚函数表中指向第一个虚函数的地址
//cout<<(***q)<<endl; // !!!错误,提示表达式必须是指向完整类型的指针,q为void之故
//对象运行时类型识别 ,存放在vptr-1处的内存中
//cout<<*((*q)-1)<<endl; //
//下面两种表示方式意义相同
//cout<<*((*q)+1)<<endl; //虚函数表中指向第二个虚函数的地址
cout<<(*q)[1]<<endl;
//cout<<*((*q)+2)<<endl; //虚函数表中指向第3个虚函数的地址
cout<<(*q)[2]<<endl;
//cout<<*((*q)+3)<<endl; //虚函数表中指向第4个虚函数的地址
cout<<(*q)[3]<<endl;
//cout<<*((*q)+4)<<endl; //虚函数表中指向第5个虚函数的地址
cout<<(*q)[4]<<endl;
//cout<<*((*q)+5)<<endl; //虚函数表中指向第6个虚函数的地址
cout<<(*q)[5]<<endl;
pFun = (Fun)(**q);
pFun();
pFun = (Fun)((*q)[1]);
pFun();
pFun = (Fun)((*q)[2]);
pFun();
pFun = (Fun)((*q)[3]);
pFun();
pFun = (Fun)((*q)[4]);
pFun();
pFun = (Fun)((*q)[5]);
pFun();
system("pause");
return 0;
}