zoukankan      html  css  js  c++  java
  • 类的成员函数指针和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),后者是一个自由函数类型的指针,可以自由调用。

    完毕。

  • 相关阅读:
    CSS学习笔记之(1):文档流、块级元素、内联元素
    java nio纯理论
    CSS权重计算
    JS闭包(转载)
    [Journal]我是如何DIY博客的
    [CodeForces]Codeforces Round #428 (Div. 2)
    [Data Structure][线段树]BZOJ3211 花神游历各国
    [Journal]有一种感动叫ACM——记WJMZBMR在成都赛区开幕式上的讲话
    美团面试失败(Java开发)
    继承的初始化过程
  • 原文地址:https://www.cnblogs.com/inevermore/p/4014429.html
Copyright © 2011-2022 走看看