在类的外面调用类保护类型的虚函数

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class A{ 
protected:
virtual void fun(){
	printf("class:a		function:fun\n");
}
virtual void fun2(){
	printf("class:a		function:fun2\n");
}
};
class B:public A{
protected:
void fun(){
	printf("class:b		function:fun\n");
}
void fun2(){
	printf("class:b		function:fun2\n");
}
};


int main(){
	//输入和输出重定向  
    freopen("in.txt","r", stdin);  
    freopen("out.txt", "w", stdout); 
	void (*fun)(A*); 
	A* pa = new B(); 
	long fp; 
	memcpy(&fp, pa, 4); 
	memcpy(&fun, reinterpret_cast<long*>(fp), 4); 
	fun(pa); 
	memcpy(&fun, reinterpret_cast<long*>(fp)+1, 4); 
	fun(pa); 
	delete pa; 
    return 0; 
}

 输出结果如下:

class:b function:fun

class:b function:fun2

 

百度百科的解释:

void (*fun)(A*); 这段定义了一个 函数指针名字叫做fun,而且有一个A*类型的参数,这个函数指针待会儿用来保存从vtbl里取出的函数地址
A* p=new B(); new B是向内存(内存分5个区:全局名字空间,自由存储区,寄存器,代码空间,栈)自由存储区申请一个内存单元的地址然后隐式地保存在一个 指针中.然后把这个地址赋值给A类型的指针P.
.
long fp; 这个long类型的 变量待会儿用来保存vptr的值
memcpy(&fp,pa,4); 前面说了,他们的实例对象里只有vptr 指针,所以我们就放心大胆地把pa所指的4bytes内存里的东西复制到fp中,所以复制出来的4bytes内容就是vptr的值,即vtbl的地址
现在有了vtbl的地址了,那么我们现在就取出vtbl第一个slot里的内容
memcpy(&fun, reinterpret_cast<long*>(fp), 4); 取出vtbl第一个slot里的内容,并存放在 函数指针fun里。需要注意的是fp里面是vtbl的地址,但fp不是 指针,所以我们要把它先转变成指针类型
fun(pa); 这里就调用了刚才取出的函数地址里的函数,也就是调用了B::fun()这个函数,也许你发现了为什么会有参数p,其实类 成员函数调用时,会有个this 指针,这个p就是那个this指针,只是在一般的调用中 编译器自动帮你处理了而已,而在这里则需要自己处理

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值