类的成员函数指针和mem_fun适配器的用法

先来看一个最简单的函数:

void foo(int a)
{
    cout << a << endl;
}

它的函数指针类型为

void (*)(int);

我们可以这样使用:

void (*pFunc)(int) = &foo;
pFunc(123);

这就是函数指针的基本使用。

 

类的成员函数

 

那么,对于类的成员函数,函数指针有什么不同呢?

我们观察下面的类:

class Foo
{
public:

    //void (Foo::*)(int)
    void foo(int a)
    {
        cout << a << endl;
    }

    //void (*)(int)
    static void bar(int a)
    {
        cout << a << endl;
    }
};

我们尝试使用:

void (*pFunc)(int) = &Foo::foo;

得到编译错误:

error: cannot convert ‘void (Foo::*)(int)’ to ‘void (*)(int)’ in initialization

从上面的编译错误,我们可以得知,foo的函数指针类型绝对不是我们期望的void (*)(int),而是void (Foo::*)(int)。

原因很简单,类的成员函数,含有一个隐式的参数this,所以foo实际是存在两个参数,Foo*和int。

那么我们尝试使用void (Foo::*)(int)类型,如下:

void (Foo::*pFunc2)(int) = &Foo::foo;

那么如何调用呢,我们采用下列两种方式:

Foo f;
(f.*pFunc2)(45678);

以及

Foo *pf = &f;
(pf->*pFunc2)(7865);

此时的使用方式是正确的。

 

那么bar函数是static函数,它具有什么特点呢?

void (*pFunc)(int) = &Foo::bar;
 pFunc(123);

我们发现,static函数和自由函数的指针类型一致。

 

既然foo含有一个隐式参数,那么能否将其转化出来呢?我们使用STL中的mem_fun,这是一种函数适配器。

Foo f;
//void (Foo::*)(int) -> void (*)(Foo*, int)
(mem_fun(&Foo::foo))(&f, 123);

我们可以看到,mem_func起到一种转化作用,将void (Foo::*)(int)类型的成员函数指针转化为void (*)(Foo*, int),后者是一个自由函数类型的指针,可以自由调用。

 

完毕。

时间: 2024-10-13 16:19:10

类的成员函数指针和mem_fun适配器的用法的相关文章

C++——类的成员函数指针以及mem_fun适配器

有这样一个类,我们以此类为基础: 1 class Foo 2 { 3 public: 4 5 //void (Foo::*)(int) 6 void foo(int a) 7 { 8 cout << a << endl; 9 } 10 11 //void (*)(int) 12 static void bar(int a) 13 { 14 cout << a << endl; 15 } 16 }; 我们尝试调用函数指针: void (*pFunc)(int)

类的成员函数指针(比較深入)

From:http://blog.csdn.net/hairetz/archive/2009/05/06/4153252.aspx 个人感觉对于类的成员函数指针这块解说的比較深入具体 推荐阅读 ///////////////////////////////////////////////// 先看这样一段代码 class test {    public:       test(int i){ m_i=i;}       test(){} void hello()       {        

VB6/VBA中跟踪鼠标移出窗体控件事件(类模块成员函数指针CHooker类应用)

前几天发了一篇博文,是关于获取VB类模块成员函数指针的内容(http://www.cnblogs.com/alexywt/p/5880993.html):今天我就发一下我的应用实例. VB中默认是没有鼠标移出事件响应的,而这个事件其实在项目开发中,实用性很强,很多时候需要在鼠标移出窗体或控件时做些事情:没有这个事件会感觉很费力: 今天我所说的实际案例就是,在窗体上,设计一个SplitterBar控件,窗体的最终用户使用这个控件可以在运行程序时任意调整其内部控件大小. 我在第二篇参考博文作者开发的

类的成员函数指针

一个类的成员函数指针使用前,必须添加一个类的对象. 普通类的成员函数指针建立: 返回值 (类名::指针名)(函数参数)=void (A::*pt)(int,bool); 初级实例代码一: 1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 void set(int x,int y){i=x,j=y;} 8 int get(){return i*j;} 9 private: 10 int i; 11 i

C++类的成员函数的指针和mem_fun适配器的用法

一.普通函数指针 我们先来看一个最简单的函数: void fool(int a) { cout << a<< endl; } 那么它的函数指针类型为: void (*) (int) 我们可以这样测试: void (*pFunc)(int) = &foo;//这里pFunc是个指针 pFunc(123); 这样就会打印出整数123:为了简化,我们可以使用typedef: typedef void (*pFunc)(int); 这里我们要说明一下: 这里的pFunc是 返回值为

获取VB类模块成员函数指针(转)

最近在做一些VB6.VBA的项目,被如何获取类模块中的函数指针这个问题所困扰,收集整理后,有2分资料值得收藏,特将关键部分留存,以备后续查找. 参照连接1:http://www.cnblogs.com/pctgl/articles/1352916.html 参照连接2:http://blog.csdn.net/lyserver/article/details/4224676 以下是链接1中的部分内容: 1. 函数地址 = GetClassProcAddress ( 指定为哪个函数 [上面解释],

成员函数指针与高性能的C++委托

成员函数指针与高性能的C++委托(上篇) 撰文:Don Clugston 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做"闭包(closure)"或"委托 (delegate)")在一些语言中已经证明了它宝贵的价值.在Delphi (Object Pascal)中,面向对象的函数指针是Borland可视化组建库(VCL,Visual Component Library)的基础.而在目前,C#使"委托&

C++学习之成员函数指针

C++中有函数指针,申明方式如下: void(*p)(float) 其中p就是一个函数指针,如果我们定义一个函数 void fun(float) 那么我们可以p = fun 或者p = &fun来给p赋值 于此同时还有一个概念叫做成员函数指针,这个指针和函数指针类似,所不同的是它是一个指向类的成员函数的指针,其声名方式如下: void (class_name::*p)(float) 这就代表p是一个指向class_name类中形如void fun_name(float)的函数的函数指针 赋值的方

一般函数指针与成员函数指针

函数指针,顾名思义,指向函数的指针. C++中函数指针的声明形式为: void (*pfn)() C++中函数指针的赋值:pfn=funName 或 &funName C++中函数指针的使用:pfn() 或(*fun)() 看到了上面的赋值跟使用的时候,我们不禁会产生疑问,为什么指针的赋值可以用函数名?又可以用取地址的形式赋值呢?为什么可以通过指针可以直接调用函数呢?指针不是需要解引用才能访问指向的内容吗?这个我表示也暂时不理解编译器编译的时候的具体赋值细节.不过这里我们可以先把函数名,当作数组