【C++】【虚函数表】超详细介绍
######以下介绍都为本人个人理解###### ######如有理解错误可到下方留言######
我会用以下的例子介绍【 虚函数表 】
(一)首先介绍:Father 类 CPP测试代码
1:该代码是创建了一个名为Father的类。
2:类里面 在三个成员函数前面添加了:virtual 表示这三个成员函数声明为虚函数。
Father 类 CPP测试代码
#include <iostream>
using namespace std;
class Father {
public:
virtual void func1() {
cout << "Father::func1()
"; }
virtual void func2() {
cout << "Father::func2()
"; }
virtual void func3() {
cout << "Father::func3()
"; }
};
(二)【虚函数表图】介绍其原理
1:根据 Father 类 CPP测试代码,从最左边的模型来看首先创建一个 father 对象。
2:对象 father 的首地址,存放的是一个虚函数表指针,暂且命名为 :vptr
3:【虚函数表指针】根据上图是指向 [ 虚函数表 ] 中的 [ 第一个虚函数 ] 的地址。
4:那么知道了这些,我们要怎么去访问该虚函数呢? 请看【以下代码】。
.
(三)该代码是在 Father 类 CPP 测试代码基础上增加了测试主函数。
Father 类 CPP测试代码
#include <iostream>
using namespace std;
class Father {
public:
virtual void func1() {
cout << "Father::func1()
"; }
virtual void func2() {
cout << "Father::func2()
"; }
virtual void func3() {
cout << "Father::func3()
"; }
};
typedef void(*func_t)();
// 测试函数
int main(void) {
Father father;
int* vptr = (int*)*(int*)(&father);
cout << "
调用第一个虚函数:"; ((func_t) * (vptr + 0))();
cout << "
调用第二个虚函数:"; ((func_t) * (vptr + 1))();
cout << "
调用第三个虚函数:"; ((func_t) * (vptr + 2))();
system("pause");
return 0;
}
1:创建对象 father
2:定义 int 类型指针:vptr
3:vptr 被赋值于对象 father 取地址之后 强制类型转换为 int 类型指针,因为对象 father 地址存放的是一个虚函数表指针。然后再通过 * 解引获得虚函数表中的:Father::func1() 的地址。最后再转换成 int 类型指针,因为 vptr 是一个指针,所以必须再转换成 int 类型指针才能赋值给 vptr,此时的 vptr 指针存放的就是虚函数表中的第一个:Father::func1() 的地址
4:最后定义【函数指针】:typedef void( * func_t) (); 通过 函数指针 访问 【虚函数】
5:使用 cout 打印输出,vptr + 0 就是第一个虚函数,与数组相似,每加1就是访问下一个虚函数,通过 * vptr 解引后就得到了第一个虚函数地址,然后使用函数指针:(func_t) 访问到第一个虚函数。以此类推,加1就是访问第二个虚函数,加2就是访问三个虚函数。 .
代码输出效果:
以上皆是个人看法及理解,如有错误与意见可在下方留言。
