对类成员函数的另类调用方法

/*

语言: C++

工程: VS / win32 / 空项目

简介:该例演示了在没有类实例存在的情况下,对类方法的调用,同时也证明了虚函数表是不依赖于对象实例而存在的

*/

#include <iostream>
#include <stdlib.h>
using namespace std;
typedef unsigned long ULONG;
class A
{
public:
	virtual void func1(){cout<<"A::this is virtual func1"<<endl;}
	virtual void func2(){cout<<"A::this is virtual func2"<<endl;}
	virtual void func3(){cout<<"A::this is virtual func3"<<endl;}
};


class A2:public A
{
public:
	void func1(){cout<<"A2::this is virtual func1"<<endl;}
	void func2(){cout<<"A2::this is virtual func2"<<endl;}
	void func3(){cout<<"A2::this is virtual func3"<<endl;}
};


struct PV
{
	ULONG p2;
};


void func(PV *p)
{
	//实验一
	A2 a2;
	ULONG l;
	l=*(ULONG*)&a2;
	//l=0x00417700;	//试验二
	(*p).p2=l;
}

int main()
{
/*试验二
	A2 a2;
	ULONG l;
	l=*(ULONG*)&a2;
*/
/*实验三
	A a1;
	ULONG l;
	l=*(ULONG*)&a1;
*/
	PV pv;
	func(&pv);
	A* pa=NULL;
	pa=(A*)&pv;
	pa->func1();
	pa->func2();
	pa->func3();
	system("pause");
}


试验一、二证明,对类中的(非静态)方法的调用,并与一定需要有类实例的存在,而只要这个实例“曾经存在过”(影响虚表的创建)就行了。
试验证明,虚函数表是在编译时遇到第一个对象的定义时(A2 a2;)才创建的(仍在编译期),如果整个程序没有类实例,则不会创建虚函数表。
但如果一个基类没有创建相应实例,而其派生类创建了相应实例,则该基类也会默认生成虚函数表。
如果一个类中含有数据成员,且其方法涉及对自身数据成员的操作(大多数的类都是这样的),则尽管可以想上面那样“无实例调用类方法”,
但这样的调用时没有意义的,所以对于这样的类,需要关注类实例的存在性。
(通过分析汇编代码可知),类指针(接口指针)调用类方法时,如果是调用的非虚函数成员,则实际在编译时,就转化为函数代码地址了;
而对于虚成员函数的调用,则在编译时,转化为对虚汗表的查表运算。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值