每次被问到虚表在哪都感觉自己答错了,真的难受。
Ubuntu18+Clion默认编译器,64位机器测试。
#include<iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class A
{
private:
int x;
long long xy;
int y;
public:
virtual void f1(void)
{
cout<<"A::f1"<<endl;
}
virtual void f2(void)
{
cout<<"A::f2"<<endl;
}
};
void normal_func1(){};
void normal_func2(){};
void normal_func3(){};
int global_int = 0;
int main()
{
static int static_int = 0;
static int static_uni;
int *pHeapInt = new int[10];
cout<<"(long*)normal_func1 "<<(long*)(normal_func1)<<endl;
cout<<"(long*)normal_func2 "<<(long*)(normal_func2)<<endl;
cout<<"(long*)normal_func3 "<<(long*)(normal_func3)<<endl;
cout<<"(long*)(&global_int) "<<(long*)(&global_int)<<endl;
cout<<"(long*)(&static_int) "<<(long*)(&static_int)<<endl;
cout<<"(long*)(&static_uni) "<<(long*)(&static_uni)<<endl;
cout<<"pHeapInt "<<(pHeapInt)<<endl;
cout<<"&pHeapInt "<<(&pHeapInt)<<endl;
typedef void(*Fun)(void);
A virtual_instance0, virtual_instance1, virtual_instance2;
A *vip1 = new A();
cout<<endl<<endl<<"虚函数相关: "<<endl<<endl;
cout << "(long*)(&vip1): " << (long*)(&vip1) << endl;
cout << "(long*)(vip1): " << (long*)(vip1) << endl;
cout << "(long*)*(long*)(vip1): " << (long*)*(long*)(vip1) << endl;
cout << "(long*)(&virtual_instance0) " << (long*)(&virtual_instance0) << endl;
cout << "(long*)(&virtual_instance1) " << (long*)(&virtual_instance1) << endl;
cout << "(long*)*(long*)(&virtual_instance0) " << (long*)*(long*)(&virtual_instance0) << endl;
cout << "(long*)*(long*)(&virtual_instance1) " << (long*)*(long*)(&virtual_instance1) << endl;
cout << "*(long*)*(long*)(&virtual_instance0) " << hex<<"0x"<<*(long*)*(long*)(&virtual_instance0) << endl;
cout << "*(long*)*(long*)(&virtual_instance1) " << hex<<"0x"<<*(long*)*(long*)(&virtual_instance1) << endl;
Fun pFunc1, pFunc2;
// pFunc1 =
pFunc1 = (Fun)*((long*)*(long*)(&virtual_instance0));
pFunc1();
pFunc2 = (Fun)*((long*)*(long*)(&virtual_instance0) + 1);
pFunc2();
return 0;
}
输出:
(long*)normal_func1 0x55a668f47b8a
(long*)normal_func2 0x55a668f47b91
(long*)normal_func3 0x55a668f47b98
(long*)(&global_int) 0x55a669149134
(long*)(&static_int) 0x55a66914913c
(long*)(&static_uni) 0x55a669149140
pHeapInt 0x55a66a59be70
&pHeapInt 0x7ffe4ad31f80
虚函数相关:
(long*)(&vip1): 0x7ffe4ad31f88
(long*)(vip1): 0x55a66a59c2b0
(long*)*(long*)(vip1): 0x55a669148d40
(long*)(&virtual_instance0) 0x7ffe4ad31fa0
(long*)(&virtual_instance1) 0x7ffe4ad31fc0
(long*)*(long*)(&virtual_instance0) 0x55a669148d40
(long*)*(long*)(&virtual_instance1) 0x55a669148d40
*(long*)*(long*)(&virtual_instance0) 0x55a668f48288
*(long*)*(long*)(&virtual_instance1) 0x55a668f48288
A::f1
A::f2
整理:
如果对应的归纳整理没错的话,先生成普通函数,然后生成虚函数,虚函数表是在虚函数生成之后就生成的,应该是在代码区。
然后 还有几个问题没有搞定:
- 虚函数表是否生成与某个类是否有对象实例化有关吗?即未实例化的类会不会生成虚函数表?
- 假如虚函数表被更改了,如何知道修改者是谁?