函数指针在指向全局的函数时与类的成员函数时编译器解析地址常常是不同的,所以导致指向全局函数的函数指针无法指向类的成员函数(code1.cpp第26行)。
类的成员函数指针声明时需要加上类名作为限定域(code1.cpp第4行),并且访问时仅能用该类的对象访问(code1.cpp第31行)。
另外需要说明类的静态成员函数行为与全局函数相近,不同于类的成员函数,本文没有特别说明,“成员函数”均是只的非静态成员函数。
1 // code1.cpp 2 3 typedef void (*Func)(); 4 typedef void (B::*BFunc)(); 5 6 void func() 7 { 8 cout<<"Global function."<<endl; 9 } 10 11 class B { 12 public: 13 void func() 14 { 15 cout<<"B function."<<endl; 16 } 17 }; 18 19 int main() 20 { 21 Func pFun = &func; 22 // Func pFun = func; // correct 23 (*pFun)(); 24 25 B b; 26 // pFun = &B::func; // wrong 27 // (*pFun)(); 28 29 BFunc pBFun = &B::func; 30 // BFunc pBFun = B::func; // wrong 31 (b.*pBFun)(); 32 33 return 0; 34 }
本文提出的问题是笔者在肽段序列加修饰的时候遇到的,但涉及到设计模式,程序结构的范畴,有广泛的适用性,因此有了这篇博文。
肽段序列加修饰因为在多个搜索流程中都会用到,如果在每个流程中都重复写一样的代码,仅仅有几个句子不同,那就有必要将这个过程抽象为一个类,为多个流程服务。这个抽象出的类服务于肽段,为肽段加了一个额外的部件,因此可以看做是Decorator模式(code2.cpp第14-22行),由它装饰过的肽段与普通的肽段使用起来是一样的。而后问题产生了,抽象出的服务会加可变修饰,以递归枚举的形式完成,每生成一种修饰形式会调用下一个操作,而不会将所有的修饰形式都存储后再扫描,虽然枚举生成修饰肽段的过程完全一致,但调用一下个操作却因流程而异,所以想到了用函数指针的方式传参数。然而,传入的函数参数来自不同类的成员函数,如何能用一个接口实现多个类的调用,能想到的唯一方式就是用泛型,将类型名与函数指针的类型作为类的参数传入(code2.cpp第14行)。因此这个问题的解决方案就是泛型与函数指针结合。
1 // code2.cpp 2 3 #include <vector> 4 #include <string> 5 #include <iostream> 6 7 using namespace std; 8 9 class FlowB; 10 class FlowC; 11 typedef void (FlowB::*BFunc)(); 12 typedef void (FlowC::*CFunc)(); 13 14 template<typename Invoke, typename Func> 15 class Decorator { 16 public: 17 void decorate(Invoke *pFlow, Func fun) 18 { 19 cout<<"decorate.. ."; 20 (pFlow->*fun)(); 21 } 22 }; 23 24 class FlowB { 25 Decorator<FlowB, BFunc> *m_pDecorator; 26 27 public: 28 void func() 29 { 30 cout<<"Flow B function."<<endl; 31 } 32 void func2() 33 { 34 cout<<"Flow B another function"<<endl; 35 } 36 37 void g() 38 { 39 m_pDecorator = new Decorator<FlowB, BFunc>(); 40 m_pDecorator->decorate(this, &FlowB::func); 41 m_pDecorator->decorate(this, &FlowB::func2); 42 delete m_pDecorator; 43 } 44 }; 45 46 class FlowC { 47 Decorator<FlowC, CFunc> *m_pDecorator; 48 49 public: 50 void func() 51 { 52 cout<<"Flow C function"<<endl; 53 } 54 55 void g() 56 { 57 m_pDecorator = new Decorator<FlowC, CFunc>(); 58 m_pDecorator->decorate(this, &FlowC::func); 59 delete m_pDecorator; 60 } 61 }; 62 63 int main() 64 { 65 FlowB b; 66 b.g(); 67 68 FlowC c; 69 c.g(); 70 return 0; 71 }
参考链接:
[1] Pointers to Member Functions
[2] Can a single function pointer point to multiple classes member function
让相同参数的函数指针指向两个不同类的多个成员函数,布布扣,bubuko.com
原文:http://www.cnblogs.com/foreverinside/p/3600325.html