C++类函数指针的使用(收藏)
时间:2010-09-07 来源:wwm
原文地址:http://blogger.org.cn/blog/more.asp?name=oceanblue&id=6721
在 注册一个回调函数时候,我们常常使用函数指针.c++\c的连接器在连接程序的时候必须把函数的调用语句上,因此函数地址必须在编译时就确定下来.也就是 编译器为函数生成代码的时候.
typedef int(* FuncPtr)(const char*) 定义一个函数指针的类型
类的成员函数有4种类型:inline,virtual,static,normal。inline函数在运行时会展开,虽然语言允许 取其地址,但是没有太大的意义.virtual成员函数的地址指的是其在vtable中的位置;static成员函数的地址和普通全局函数的地址没有任何 区别;普通成员函数的地址和一般函数的地址也没有区别,就是函数代码在内存中的真实地址,但是由于它的调用要绑定到一个实在实在在的对象身上,因此无论是 其函数指针的声明方式还是其地址的获取方式都比较特别.
代码如下:
#include<iostream.h>
class CTest
{
public:
void f(void) //普通成员函数
{
cout<<"CTest::f()"<<endl;
}
static void g(void) //静态成员函数
{
cout<<"CTest::g()"<<endl;
}
virtual void h(void) //虚拟的成员函数
{
cout<<"CTest::h()"<<endl;
}
};
int main()
{
typedef void (*GFPtr)(void); //定义 一个全局函数指针类型
GFPtr fp=CTest::g; //取静态 成员函数地址的方法和取一个全局函数的地址相似
fp(); //通过函数 指针调用类静态成员函数
typedef void (CTest::*MemFuncPtr)(void); //声明类成员函数指针类型
MemFuncPtr mfp_1=&CTest::f; //声明成员函数指针变量并初始化
MemFuncPtr mfp_2=&CTest::h; //注意获得成员函数地址的方法
CTest theObj;
(theObj.*mfp_1)(); //使用对象和成员函数指针调用 成员函数
(theObj.*mfp_2)();
CTest *pTest=&theObj; //使用对象指针和成员函数指针调用成员函数
(pTest->*mfp_1)();
(pTest->*mfp_2)();
retun 0;
}
实际上,任何成员函数的代码体都是独立于类的对象而存在的,只是非静态成员函数在调用的时候需要与具体的对象建立绑定关系而已(即this指 针),c++\c编译器最终把所有的成员函数经过Name-Mangling的处理后转换全局函数,并且增加一个入参this作为第一个参数,供所属类的 所有对象共享.因此成员函数的地址实际上就是这些全局函数的地址.
在 注册一个回调函数时候,我们常常使用函数指针.c++\c的连接器在连接程序的时候必须把函数的调用语句上,因此函数地址必须在编译时就确定下来.也就是 编译器为函数生成代码的时候.
typedef int(* FuncPtr)(const char*) 定义一个函数指针的类型
类的成员函数有4种类型:inline,virtual,static,normal。inline函数在运行时会展开,虽然语言允许 取其地址,但是没有太大的意义.virtual成员函数的地址指的是其在vtable中的位置;static成员函数的地址和普通全局函数的地址没有任何 区别;普通成员函数的地址和一般函数的地址也没有区别,就是函数代码在内存中的真实地址,但是由于它的调用要绑定到一个实在实在在的对象身上,因此无论是 其函数指针的声明方式还是其地址的获取方式都比较特别.
代码如下:
#include<iostream.h>
class CTest
{
public:
void f(void) //普通成员函数
{
cout<<"CTest::f()"<<endl;
}
static void g(void) //静态成员函数
{
cout<<"CTest::g()"<<endl;
}
virtual void h(void) //虚拟的成员函数
{
cout<<"CTest::h()"<<endl;
}
};
int main()
{
typedef void (*GFPtr)(void); //定义 一个全局函数指针类型
GFPtr fp=CTest::g; //取静态 成员函数地址的方法和取一个全局函数的地址相似
fp(); //通过函数 指针调用类静态成员函数
typedef void (CTest::*MemFuncPtr)(void); //声明类成员函数指针类型
MemFuncPtr mfp_1=&CTest::f; //声明成员函数指针变量并初始化
MemFuncPtr mfp_2=&CTest::h; //注意获得成员函数地址的方法
CTest theObj;
(theObj.*mfp_1)(); //使用对象和成员函数指针调用 成员函数
(theObj.*mfp_2)();
CTest *pTest=&theObj; //使用对象指针和成员函数指针调用成员函数
(pTest->*mfp_1)();
(pTest->*mfp_2)();
retun 0;
}
实际上,任何成员函数的代码体都是独立于类的对象而存在的,只是非静态成员函数在调用的时候需要与具体的对象建立绑定关系而已(即this指 针),c++\c编译器最终把所有的成员函数经过Name-Mangling的处理后转换全局函数,并且增加一个入参this作为第一个参数,供所属类的 所有对象共享.因此成员函数的地址实际上就是这些全局函数的地址.
相关阅读 更多 +