单一继承下无虚函数覆盖__虚函数表中的虚函数指针的获取

#include <iostream>
#include <string>
#include <vector>
#include <cctype>
using namespace std;

//单一继承下无虚函数覆盖
//派生类只有一个虚函数表,派生类对象只有一个虚指针来指向这个虚函数表。虚函数表中按照基类虚函数、派生类新增的虚函数顺序依次排列。

//要注意的是一旦将指针p转换成void*(或void**)时,*p(或**p会由于编译器不知道指向内存大小而出错),中间这里采用的是转换为int型;
//最后得到函数指针时,要强制转换为 虚函数指针的类型才能得到正确值

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;}

};

//定义函数指针<span style="color:#FF0000;">变量</span>testFun
//  void (*testFun)();

//定义函数指针<span style="color:#FF0000;">类型</span>
typedef void (*Fun)();

int main()
{
	Base base;
	void** p = (void**)&base;  
	
	Fun pFun = NULL;
	cout << "base对象地址:" << (&base) << endl;
	cout << "base对象中存放虚指针单元的内存地址:" << (void*)(&base) << endl;
	cout << "虚函数表的地址,即vptr指针的值:" <<(int*)*(int*)(&base) << endl;
	cout << "虚函数表中第1个虚函数的地址:" <<(Fun)*(int*)*(int*)(&base) << endl;   // 虚函数表中存放的是指向虚函数的指针,因此必须转换成虚函数指针类型,而Fun为函数指针类型
	cout << "虚函数表中第1个虚函数的地址:" <<(void*)*(int*)*(int*)(&base) << endl; 
	cout << "虚函数表中第2个虚函数的地址:" <<(Fun)*((int*)*(int*)(&base)+1)<< endl;
	cout << "虚函数表中第3个虚函数的地址:" <<(Fun)*((int*)*(int*)(&base)+2)<< endl;
	

	cout<<p<<endl;  // base对象地址;
	cout<<*p<<endl;  // 虚函数表的地址
	//cout<<**p<<endl; //不能直接输出**p,**p类型为void,此时编译器不知道如何解释地址中内存大小和内容,需转换类型
	cout<<(Fun)(*(int*)(*p))<<endl;
	cout<<(Fun)(*((int*)(*p)+1))<<endl;
	cout<<(Fun)(*((int*)(*p)+2))<<endl;

	
	//利用上述函数指针调用相关函数,两种使用方式均可
	pFun = (Fun)(*(int*)(*p));
	pFun();  //调用方式1
       (*pFun)();  //调用方式2
        pFun = (Fun)(*((int*)(*p)+1));
	pFun();
	pFun = (Fun)(*((int*)(*p)+2));
	pFun();

	Derive derive;
	void** q = (void**)&derive;  
	cout << "derive对象地址:" << (&derive) << endl;
	cout << "derive对象中存放虚指针单元的内存地址:" << (int*)(&derive) << endl;
	cout << "虚函数表的地址,即vptr指针的值:" <<(int*)*(int*)(&derive) << endl;
	cout << "虚函数表中第1个虚函数的地址:" <<(Fun)*(int*)*(int*)(&derive)<< endl;
	cout << "虚函数表中第2个虚函数的地址:" <<(Fun)*((int*)*(int*)(&derive)+1)<< endl;
	cout << "虚函数表中第3个虚函数的地址:" <<(Fun)*((int*)*(int*)(&derive)+2)<< endl;
	//下面derive类专属的3个虚函数局部变量在VS中跟踪不到,只能显示上面3个
	cout<<"derive新增的虚函数地址如下:\n";
	cout << "虚函数表中第4个虚函数的地址:" <<(Fun)*((int*)*(int*)(&derive)+3)<< endl;
	cout << "虚函数表中第5个虚函数的地址:" <<(Fun)*((int*)*(int*)(&derive)+4)<< endl;
	cout << "虚函数表中第6个虚函数的地址:" <<(Fun)*((int*)*(int*)(&derive)+5)<< endl;
	
	cout<<q<<endl; 
	cout<<*q<<endl;  // 虚函数表的地址

	cout<<(Fun)(*(int*)(*q))<<endl;
	cout<<(Fun)(*((int*)(*q)+1))<<endl;
	cout<<(Fun)(*((int*)(*q)+2))<<endl;
	cout<<(Fun)(*((int*)(*q)+3))<<endl;
	cout<<(Fun)(*((int*)(*q)+4))<<endl;
	cout<<(Fun)(*((int*)(*q)+5))<<endl;
	
	
	//利用上述函数指针调用相关函数
        testFun = (Fun)(*(int*)(*q));
        testFun();
        (*testFun)();
        pFun = (Fun)(*((int*)(*q)+1));
	pFun();
	pFun = (Fun)(*((int*)(*q)+2));
	pFun();
	// 下面三个函数调用derive的增加的虚函数,说明新增加的虚函数的地址是存在于虚函数表中的,只是没有显示出来。
	pFun = (Fun)(*((int*)(*q)+3));
	pFun();
	pFun = (Fun)(*((int*)(*q)+4));
	pFun();
	pFun = (Fun)(*((int*)(*q)+5));
	pFun();
	

	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值