【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就是访问三个虚函数。 .

代码输出效果:

以上皆是个人看法及理解,如有错误与意见可在下方留言。

经验分享 程序员 微信小程序 职场和发展