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是 返回值为空,一个形参为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成员函数那样自由调用。

时间: 2024-12-03 15:01:07

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

类的成员函数的指针

前面一篇文章<函数的指针 >介绍了全局函数的指针,现在我们再来介绍一下成员函数的指针. 成员函数指针的定义: 一般形式 Return_Type (Class_Name::* pointer_name) (Argument_List); 用typedef简化的形式 Typedef Return_Type (Class_Name::* FuncPtr_Type) (Argument_List); FuncPtr_Type pFunc = NULL; //pFunc为成员函数指针的指针变量 成员函数

类的成员函数指针和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

如何使用指向类的成员函数的指针(详解!)

我们首先复习一下"指向函数的指针"如何使用? [cpp] view plain copy print? void print() { } void (*pfun)(); //声明一个指向函数的指针,函数的参数是 void,函数的返回值是 void pfun = print;   //赋值一个指向函数的指针 (*pfun)();    //使用一个指向函数的指针 比较简单,不是吗?为什么*pfun需要用()扩起来呢? 因为*的运算符优先级比()低,如果不用()就成了*(pfun()).

类成员函数的指针与多态性

1 类成员函数的指针 2 类成员函数的指针数组 3 指向类成员函数的指针的指针 1 类成员函数的指针 auto func1 = &com::jia;//C++函数指针 int (com::*p)(int, int) = &com::jia;//C函数指针 1 #include <iostream> 2 3 class com 4 { 5 private: 6 int a; 7 int b; 8 public: 9 com(int x, int y) :a(x), b(y) 10

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

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++: 指向类成员函数的指针

指向函数的指针有和指向类成员函数的指针的有什么不同? int f(char a, float b);如果它是普通函数,则它的类型是 int (*)(char, float);如果它是非静态成员函数,则它的类型是 int(ClassName::*)(char, float);如果它是静态成员函数,则它的类型是和普通函数一样. 如何把一个类的成员函数传递给event handler, 线程启动函数等? 类的成员函数必须和一个类的实例结合起来才有意义.可以写一个函数来包装类的成员函数. class X

(转)c++类的成员函数存储方式(是否属于类的对象)---一道面试题引发的思考

昨天去面试一家公司,面试题中有一个题,自己没弄清楚,先记录如下: class D { public: void printA() { cout<<"printA"<<endl; } virtual void printB() { cout<<"printB"<<endl; } }; main函数调用: D *d=NULL; d->printA(); d->printB(); 输出结果是? 当时想的是对象d直