C++类的成员函数的指针和mem_fun适配器的用法
2014-10-10 20:50
239 查看
一、普通函数指针
我们先来看一个最简单的函数:
那么它的函数指针类型为:
我们可以这样测试:
这样就会打印出整数123;
为了简化,我们可以使用typedef:
这里我们要说明一下:
那么我们就可以这样用:
以上就是函数指针的基本应用。
二、类的成员函数
那么,对于类的成员函数,我们该怎么声明以及应用呢?
观察下面的类:
我们在main函数中这样调用:
会发现,编译器会报出这样一条错误:
从上面的编译错误,我们得知,foo的函数指针类型不是我们期望的 void (*)(int),foo的函数指针类型其实是void (Foo::*)(int)型。
原因很简单:类的成员函数,含有一个隐式参数this,以foo为例,这里foo实际存在两个参数,一个便是this指针,另一个才是int型变量。
我们尝试使用 void (Foo::*)(int)类型,代码如下:
我们该如何使用呢?有以下两种方式:
这里我们还注意到,上述类中含有一个static成员函数,它有什么特点呢?
我们在main函数调用以上代码,发现能成功运行。这是由于static成员的特性决定的:
完整代码如下:
三、mem_fun适配器:
头文件:<functional>
既然foo含有一个隐式参数,那么能否将其转化出来呢?我们使用STL中俄mem_fun,这是一种函数适配器。
mem_fun的具体作用是一种转化作用,将void (Foo::*)(int)类型的成员函数指针转化为void (Foo*, int),后者是一个自由函数类型的指针,可以像static成员函数那样自由调用。
我们先来看一个最简单的函数:
void fool(int a) { cout << a<< endl; }
那么它的函数指针类型为:
void (*) (int)
我们可以这样测试:
void (*pFunc)(int) = &foo;//这里pFunc是个指针 pFunc(123);
这样就会打印出整数123;
为了简化,我们可以使用typedef:
typedef void (*pFunc)(int);
这里我们要说明一下:
这里的pFunc是 返回值为空,一个形参为int型的函数类型 的一个别称;即pFucn为一个类型,我们可以把pFunc类比为int,double。
那么我们就可以这样用:
#include<iostream>
#include <string>
using namespace std;
void fool(int a) { cout << a<< endl; }
int main(int argc, const char *argv[])
{
typedef void (*pFunc)(int);
pFunc fc = &fool;//fc就相当于一个变量(函数指针)
fc(1223);
return 0;
}
以上就是函数指针的基本应用。
二、类的成员函数
那么,对于类的成员函数,我们该怎么声明以及应用呢?
观察下面的类:
class Foo { public: void foo(int a) { cout << a << endl; } static void bar(int a) { cout << a << endl; } };
我们在main函数中这样调用:
void (*pFunc)(int) = &Foo::foo;
会发现,编译器会报出这样一条错误:
error: cannot convert ‘void (Foo::*)(int)’ to ‘void (*)(int)’ in initialization
从上面的编译错误,我们得知,foo的函数指针类型不是我们期望的 void (*)(int),foo的函数指针类型其实是void (Foo::*)(int)型。
原因很简单:类的成员函数,含有一个隐式参数this,以foo为例,这里foo实际存在两个参数,一个便是this指针,另一个才是int型变量。
我们尝试使用 void (Foo::*)(int)类型,代码如下:
void (Foo::*pFunc2) (int) = &Foo::foo;
我们该如何使用呢?有以下两种方式:
Foo f; //对象通过 . 方式调用 (f.*pFunc2)(12345);
Foo *pf = &f ;//对象指针通过 -> 方式调用 (pf->*pFunc2)(123124);
这里我们还注意到,上述类中含有一个static成员函数,它有什么特点呢?
void (*pFunc)(int) = &Foo::bar;//ok pFunc(123);
我们在main函数调用以上代码,发现能成功运行。这是由于static成员的特性决定的:
static将本函数声明为本类所有,而不是单个类的对象。因此我们可以想使用普通函数那样使用static成员函数。
完整代码如下:
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
class Foo { public: void foo(int a) { cout << a << endl; } static void bar(int a) { cout << a << endl; } };
int main(int argc, const char *argv[])
{
//veersion 1
//void (*pFunc)(int) = &Foo::foo;//error
//Foo::foo 的形式参数有两个:一个隐式,一个int
//void (*pFunc)(int)的形式参数只有一个
// pFunc(123);
//version 2
void (*pFunc)(int) = &Foo::bar;//ok pFunc(123);
//这里表明:static成员函数的参数没有隐式参数(本对象)
//修正1-->为其加一个参数即可
void (Foo::*pFunc2)(int) = &Foo::foo;
Foo f;
(f.*pFunc2)(12345);
Foo *pf = &f ;
(pf->*pFunc2)(123124);
return 0;
}
三、mem_fun适配器:
头文件:<functional>
既然foo含有一个隐式参数,那么能否将其转化出来呢?我们使用STL中俄mem_fun,这是一种函数适配器。
Foo f; //void (Foo::*)(int)->void (*)(Foo*,int) (mem_fun(&Foo::foo))(&f,123);
mem_fun的具体作用是一种转化作用,将void (Foo::*)(int)类型的成员函数指针转化为void (Foo*, int),后者是一个自由函数类型的指针,可以像static成员函数那样自由调用。
相关文章推荐
- 类的成员函数指针和mem_fun适配器的用法
- 类的成员函数指针和mem_fun适配器的用法
- C++之STL(九):函数适配器bind2nd 、mem_fun_ref 源码分析、函数适配器应用举例
- STL中mem_fun和mem_fun_ref的用法
- mem_fun_ref和mem_fun的用法
- STL中mem_fun和mem_fun_ref的用法 收藏
- 从零开始学C++之STL(九):函数适配器bind2nd 、mem_fun_ref 源码分析、函数适配器应用举例
- mem_fun和bind2nd的用法例子
- 【转】STL中mem_fun和mem_fun_ref的用法及区别
- STL中mem_fun和mem_fun_ref的用法
- STL中mem_fun和mem_fun_ref的用法
- STL 中 mem_fun 和 mem_fun_ref 的用法
- STL中mem_fun和mem_fun_ref的用法
- STL中mem_fun和mem_fun_ref的用法
- C++类中函数指针的用法
- STL中mem_fun和mem_fun_ref的用法
- mem_fun/mem_fun_ref用法和详解
- STL中mem_fun和mem_fun_ref的用法
- STL中mem_fun和mem_fun_ref的用法
- STL中mem_fun和mem_fun_ref的用法