对类成员函数的另类调用方法
2016-09-20 19:57
232 查看
/*
语言: 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;)才创建的(仍在编译期),如果整个程序没有类实例,则不会创建虚函数表。
但如果一个基类没有创建相应实例,而其派生类创建了相应实例,则该基类也会默认生成虚函数表。
如果一个类中含有数据成员,且其方法涉及对自身数据成员的操作(大多数的类都是这样的),则尽管可以想上面那样“无实例调用类方法”,
但这样的调用时没有意义的,所以对于这样的类,需要关注类实例的存在性。
(通过分析汇编代码可知),类指针(接口指针)调用类方法时,如果是调用的非虚函数成员,则实际在编译时,就转化为函数代码地址了;
而对于虚成员函数的调用,则在编译时,转化为对虚汗表的查表运算。
语言: 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;)才创建的(仍在编译期),如果整个程序没有类实例,则不会创建虚函数表。
但如果一个基类没有创建相应实例,而其派生类创建了相应实例,则该基类也会默认生成虚函数表。
如果一个类中含有数据成员,且其方法涉及对自身数据成员的操作(大多数的类都是这样的),则尽管可以想上面那样“无实例调用类方法”,
但这样的调用时没有意义的,所以对于这样的类,需要关注类实例的存在性。
(通过分析汇编代码可知),类指针(接口指针)调用类方法时,如果是调用的非虚函数成员,则实际在编译时,就转化为函数代码地址了;
而对于虚成员函数的调用,则在编译时,转化为对虚汗表的查表运算。
相关文章推荐
- C++成员函数指针的另类调用方法
- 获取类成员函数地址和调用的方法
- 回调函数调用类成员函数的方法
- C++线程回调函数调用类成员函数方法
- 回调函数调用类成员函数的方法
- 回调函数调用类成员函数的方法 -转贴
- FireBreath学习之三 JSAPIAuto类的成员函数说明和插件调用DOM方法/属性一般形式
- C++ 类成员函数回调调用方法
- C++静态函数中调用非静态成员函数或变量(方法1静态变量的方法)
- 类成员函数返回(成员)函数指针,包装类调用外部类的成员方法
- 不知道子类成员函数的情况下,用父类方法调用子类的成员函数指针,需增加/vmg命令
- 回调函数调用类成员函数的方法
- 父类的正常成员函数子类可以使用,并不是继承下来 的,子类是怎么调用父类的函数 : 可能是利用了一种叫函数名联编的方法.没有隐藏的情况下用函数名字来决定调用的函数.
- Java调用内部类成员函数的一个方法
- 在外部调用私有成员函数的方法
- 解决类间成员函数调用的两个方法
- 回调函数调用类成员函数的方法
- 回调函数调用类成员函数的方法
- 创建线程调用类成员函数的方法。
- 非static成员函数通过类名::来调用,空指针调用成员方法不出错!