一旦理解了一般原则,C++类成员函数指针就不那么令人生畏了。如果您正在寻找性能、复杂性或许多可能的问题解决方法,那么在涉及极端情况时,C++始终是一个不错的选择。当然,功能往往伴随着复杂性,但C++的某些特性几乎无法区分。在我看来,C++的类成员函数指针可能是我遇到过的最复杂的表达式,但我将从一些更简单的开始。文章中的示例可以在我的Github存储库中找到。C语言:函数指针让我们从一些基础知识开始:假设您有一个函数,它接受两个整数作为参数并返回一个整数:intsum(inta,intb){returna+b;}在纯C中,您可以创建指向此函数的指针,将其分配给您的sum(...)函数,并通过取消引用来调用它。函数的签名(参数、返回类型)必须与指针的签名匹配。否则,函数指针的行为类似于普通指针:int(*funcPtrOne)(int,int);funcPtrOne=∑intresultOne=funcPtrOne(2,5);如果你使用一个指针作为参数并返回一个指针,这看起来会很难看:resultTwo=*funcPtrTwo(&array[0]);C语言中的函数指针存放的是子程序的地址。指向类成员函数的指针让我们进入C++:好消息是您可能不需要使用类成员函数指针,除非在极少数情况下,例如下一个示例。首先,您已经知道定义一个类及其成员函数之一:classMyClass{public:intsum(inta,intb){returna+b;}};1.在某个类中定义一个指向成员函数的指针DeclareapointertoamemberfunctionoftheMyClassclass.此时,您不知道要调用的确切函数。您只需在MyClass类中声明一个指向任何成员函数的指针。当然,签名(参数,返回值类型)需要匹配你接下来要调用的sum(...)函数:int(MyClass::*methodPtrOne)(int,int);2.为特定函数赋值与C语言(或静态成员函数)相比,类成员函数指针不需要指向绝对地址。在C++中,每个类都有一个虚函数表(vtable),用来存放每个成员函数的地址偏移量。类成员函数指针指向vtable中的一个条目,因此它也只存储偏移量。这些原则使多态性成为可能。因为sum(...)函数的签名与您的指针声明相匹配,您可以将签名分配给它:methodPtrOne=&MyClass::sum;3.调用成员函数如果要使用指针调用类的成员函数,必须提供一个类的实例:MyClassclsInstance;intresult=(clsInstance.*methodPtrOne)(2,3);您可以使用.运算符来访问,使用*取消引用指针,方法是在调用函数时提供两个整数作为参数。很丑吧?但是你可以进一步应用它。在类中使用类成员函数指针假设您正在创建一个具有客户端/服务器原则体系结构的应用程序,该体系结构具有后端和前端。您现在不需要关心后端,相反您将拥有一个基于C++类的前端。前端依赖于后端提供的数据来完成初始化,所以需要额外的初始化机制。同时,您希望通用地实现此机制,以便将来可以使用其他初始化函数(可能是动态的)来扩展您的前端。首先定义一个数据类型来存储初始化函数(init)的指针,并描述这个函数应该在什么时候被调用(ticks):template
