[C++] 将成员函数作为函数形参

函数以及函数对象都可以作为参数来增加其它函数的功能,并且通常作为STL算法的第二个版本的最后一个参数。成员函数是否可以作为形参呢?如果可以,形参表如何写呢?

1 函数作为函数形参

    首先,成员函数作为C++中一种特殊的函数,是可以作为函数形参的。先来看一下普通函数是如何作为形参的。

   

void print(int i)
{
    cout << i << " ";
}

void func(void (*pfunc)(int), int i)
{
    pfunc(i);
}

int main()
{
    void (*pfun)(int i);
    pfun = print;
    func(pfun, 6);

    return 0;
}

上述代码有两个函数print()和func(),然后在主函数中定义了一个函数指针pfun,它的形式和print()一样,因此,可以用print()对pfun进行设置,最后,在func中使用该函数指针进行调用,当然,也可以直接使用print()。

那么,对于成员函数有什么不同呢?


2 使用成员函数指针调用成员函数

    下面来看看如何使用成员函数指针调用成员函数,以及和普通的函数有什么不同。

class A {
public:
    void fun(int a)
    {
        cout << a;
    }
};

int main()
{
    A a;
    void (A::*ptrfun)(int);
    ptrfun = &A::fun;
    (a.*ptrfun)(2);

    return 0;
}
在上述代码中,定义了一个名为A的类,类中有一个名为fun的函数。在主函数中,定义了一个A的对象a,然后定义了成员函数指针ptrfun,它的形式和A中的fun一样,于是,可以用A的fun对ptrfun进行赋值,最后使用ptrfun调用该函数。
这里有几个值得注意的问题:

(1)在对普通函数指针进行赋值时,不用加&:pfun = print,但是,对成员函数指针进行赋值时,必须加&:ptrfun = &A::fun。这涉及到函数类型与函数指针类型,对于普通函数,当定义了一个函数指针,将函数名赋值给函数指针,函数类型会默认转换成函数指针,因此pfun = print或者pfun = &print都是可行的,只是pfun = print中有一层默认的转换。而对于成员函数,当定义了一个成员函数指针ptrfun,如果直接用A::fun进行赋值,编译器会将它理解为A中的静态成员,会产生编译错误,所以,这里的&是必须的。不过,如果写成这样ptrfun = &(A::fun);也会发生编译错误,因为,将A::fun作为一个整体,编译器就会将fun理解为A中的静态成员,所以,要将&A::fun作为一个整体,即使::的优先级较高。

(2)同样,对于调用方式也有类似的不同。对于普通函数,(*pfun)()和pfun()都是可以的。对于成员函数,只能是(a.*ptrfun)()。


3 将成员函数作为函数形参

    总算到了正题。。。

    从前述知道,要将成员函数作为函数形参,只要将函数的形参设为成员函数指针,然后在函数体中调用就行。

class A {
public:
    void fun(int a)
    {
        cout << a;
    }
};

void test(A x, void (A::*pfun)(int), int y)
{
    (x.*pfun)(y);
}

int main()
{
    void (A::*ptrfun)(int);
    ptrfun = &A::fun;
    A a;
    test(a, ptrfun, 3);

    return 0;
}

上述代码定义了一个类A以及一个成员函数fun,然后在test中用fun函数类型指针作为参数进行调用,对于非静态函数的调用,必须指定对象,因此,test的第一个参数是一个对象。主函数中的代码和第2小节类似。

[C++] 将成员函数作为函数形参

上一篇:数据结构--快速、冒泡、选择排序C语言实现


下一篇:Priority_Queue 优先队列 C++学习笔记