我之前一直困惑,为啥所有代码都不能运行,现在我知道了,原来是编译器各自的实现不一样。
下面的代码主要是参考上面链接的代码写的,在vs2022和Linux上都可以运行,Linux似乎也可以运行另一种虚函数表的代码,不过因为我主要用的是vs,就不研究了。
另外关于虚函数的指针类型,用啥都行int long void ,编译器不输出结果和和这个是没有关系的。
#include <iostream>
using namespace std;
class Base
{
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
typedef void (*Fun)(void);
int main()
{
Base b;
//Fun pFun = NULL;
cout << "b 的地址: " << &b << endl;
//这里指针用啥都行int ,long,void也行
void ***vptr = (void ***) (&b);
void (*p)() = (void (*)())(vptr[0][0]);
void (*p2)() = (void (*)())(vptr[0][1]);
void (*p3)() = (void (*)())(vptr[0][2]);
//这个无意义,无法运行
//void (*p4)() = (void (*)())(vptr[0][3]);
//p4();
Fun f1 = (Fun) vptr[0][0];
Fun f2 = (Fun) vptr[0][1];
Fun f3 = (Fun) vptr[0][2];
f1();
f2();
f3();
p();
p2();
p3();
cout << "vptr 的地址: " << vptr << endl;
//vptr[1]没啥意义
cout << "vptr[0]的地址: " << &vptr[0] << endl;
cout << "vptr[1]的地址: " << *&vptr[1] << endl;
cout << "vptr[0]的指向: " << vptr[0] << endl;
cout << "vptr[0]的指向: " << *&vptr[0] << endl;
cout << "vptr[1]的指向: " << vptr[1] << endl;
cout << "vptr[0][0]的地址: " << &vptr[0][0] << endl;
cout << "vptr[0][1]的地址: " << &vptr[0][1] << endl;
cout << "vptr[0][2]的地址: " << &vptr[0][2] << endl;
//这俩无意义
cout << "vptr[0][3]的地址: " << &vptr[0][3] << endl;
cout << "vptr[0][4]的地址: " << &vptr[0][4] << endl;
cout << "vptr[0][0]的指向: " << vptr[0][0] << endl;
cout << "vptr[0][1]的指向: " << vptr[0][1] << endl;
cout << "vptr[0][2]的指向: " << vptr[0][2] << endl;
//这俩无意义
cout << "vptr[0][3]的指向: " << vptr[0][3] << endl;
cout << "vptr[0][4]的指向: " << vptr[0][4] << endl;
//pFun();
return 0;
}