函数指针--全局函数指针与类的函数指针(二)

本次对之前的说明做个补充,大体内容还是一样的。

这里对类里面的成员函数指针变量的使用继续进行了解,最主要的是希望能达到通过非静态成员指针变量来引用各自的非静态成员函数。

这样每个实例可以保存当前对象对应的功能操作,而无需再进行一些业务逻辑或者算法的计算,提高运行效率。

定义一个函数指针typedef int (T::*MFunc)(const int &, const int &);

在类T里面声明一个公有的非静态成员函数指针变量MFunc m_ProFunc;

1. 在类的非静态成员函数里面可以通过this指针对该成员变量进行操作(this->*m_ProFunc)(a, b);

2. 在类的静态成员函数外部接口函数没有this指针,同时因为非静态函数成员含有this指针的原因,则无法通过该方式进行操作m_ProFunc。当你尝试使用实例对象进行操作时,例如给一个实例的形参T* t; 然后在函数里面通过指针操作该类(t->*m_ProFunc)(a, b),就无法通过编译,因为编译器做了函数识别与校验。是的,(t->*T::m_ProFunc)(a, b)和(t->T::*m_ProFunc)(a, b)这种方式在静态成员函数或外部接口函数都无法使用。

通过调测,发现了可以使用形参的方式来让编译器识别实例对象的非静态成员函数指针变量所调用的功能,这实在让人开心,因为这样就可以实现设计要求。

这样将函数指针变量当做实参传给调用的接口,继而在接口里面进行实际的功能调用。

注意:因为使用了指针变量,这就需要对非静态成员函数指针形参进行非空校验,避免程序coredump。

综上所述,对之前的代码进行了调整,希望可以提供一定的帮助和参考:)

  • 全局函数指针的定义与调用。
    • 假设一个函数Add(), 函数声明和定义如下:
      int Add(const int &a, const int &b){ printf("Add\n"); return a + b;};
    • 全局函数指针类型声明GFunc,函数指针TFunc1:
      typedef int (*GFunc)(const int &, const int &);
      GFunc TFunc1 = Add;    //效果与显式TFunc1 = &Add一致。
      TFunc1(a, b);  //隐式调用Add,最终编译器会转为显式,按显式方式来处理
      (*TFunc1)(a, b);      //显式调用 Add
  • 类的静态函数指针的定义与调用,包括在类的内部接口定义和外部接口定义,以及调用方法。
  • 类的非静态函数指针的定义与调用,包括在类的内部接口定义和外部接口定义,以及调用方法。
    • 假设一个类T的非静态公有函数Max(), 函数声明和定义如下:
      int T::Max(const int &a, const int &b) {printf("T::Max\n");return a > b ? a : b;};
    • 类T的非静态公有函数指针类型声明MFunc,公有函数指针成员变量m_ProFunc:
      typedef int (T::*MFunc)(const int &, const int &);
      MFunc m_ProFunc;
      m_ProFunc = &T::Max;  //显式赋值,在类的非静态成员函数里面,在外部接口无法使用该方式进行赋值,只能通过类的内部函数接口的函数参数方式进行赋值
      (this->*m_ProFunc)(a, b);  //显式调用,在类的非静态成员函数里面。在外部接口或者静态接口中,只能通过形参来进行调用,具体参考下面代码
      // oparator class name
      Test1.ISetFunc(&T::Max);
      Test1.IGetFunc(a, b);
      
      // oparator non-member
      Test1.m_ProFunc = &T::Min;
      Test1.ISetFunc(Test1.m_ProFunc); Test1.IGetFunc(a, b);
  1 /* Author by [email protected] */
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <unistd.h>
  5 
  6 int Add(const int &a, const int &b){ printf("Add\n"); return a + b;};
  7 int Max(const int &a, const int &b){ printf("Max\n"); return a > b ? a : b;};
  8 int Min(const int &a, const int &b){ printf("Min\n"); return a < b ? a : b;};
  9 
 10 class T;
 11 
 12 /*Pointer to non-static member function*/
 13 typedef int (T::*MFunc)(const int &, const int &);
 14 
 15 /*Pointer to global function*/
 16 typedef int (*GFunc)(const int &, const int &);
 17 
 18 class T {
 19     public:
 20         int m_Id;
 21 
 22         MFunc m_ProFunc;
 23         static MFunc m_sProFunc;
 24 
 25     public:
 26         T(): m_Id(0), m_ProFunc(NULL) {};
 27 
 28         int Max(const int &a, const int &b) {printf("T::Max\n");return a > b ? a : b;};
 29         int Min(const int &a, const int &b) {printf("T::Min\n");return a < b ? a : b;};
 30         static int Add(const int &a, const int &b) {printf("static T::Add\n");return a + b;};
 31         static int SMFunc(T *t, MFunc func, const int &a, const int &b) {
 32             if (t == NULL) {
 33                 printf("Object is null!\n");
 34                 return -1;
 35             }
 36 
 37             if (func == NULL) {
 38                 printf("MFunc is null!\n");
 39                 return -1;
 40             }
 41 
 42             printf("That's SMFunc(%d:%d)\n", a, t->m_Id);
 43             t->m_Id = a;
 44             t->Min(a, b);
 45             //(t->*m_ProFunc)(a, b); //error invalid use of member ‘T::m_ProFunc’ in static member function
 46             (t->*func)(a, b);        //ok
 47 
 48             return t->m_Id;
 49         };
 50 
 51 
 52         int Init(const int &type) {
 53             m_Id = type;
 54             if (type == 1) {
 55                 m_ProFunc = &T::Max;
 56             } else if (type == 2) {
 57                 //m_ProFunc = &(this->Min);  // error
 58                 m_ProFunc = &T::Min;
 59             } else {
 60                 printf("unkown type\n");
 61                 return -1;
 62             }
 63 
 64             return 0;
 65         }
 66 
 67         /*Internal interface function,Encapsulate non-static member functions*/
 68         int IResult(MFunc func, const int &a, const int &b){
 69             printf("That's IResult:(%d)--->", m_Id);
 70             return (this->*func)(a, b);
 71         }
 72 
 73         int ISetFunc(MFunc func){
 74             m_ProFunc = func;  //Reset func
 75         }
 76 
 77         int IGetFunc(const int &a, const int &b) {
 78             //(*m_ProFunc)(a, b);          // error:invalid use of unary ‘*’ on pointer to member
 79             (this->*m_ProFunc)(a, b);      // ok
 80          }
 81 
 82 };
 83 
 84 MFunc T::m_sProFunc = &T::Min;
 85 
 86 /*External interface function,Encapsulate non-static member functions*/
 87 int MResult(T* p, MFunc func, const int &a, const int &b)
 88 {
 89     printf("That's Ext MResult:(%d)--->", p->m_Id);
 90     p->Min(a, b);
 91 
 92     if (func == NULL) {
 93         printf("Pointer is null!\n");
 94         return -1;
 95     }
 96         
 97     // *(p->m_ProFunc)(a, b);  must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘p->T::m_ProFunc (...)’, e.g. ‘(... ->* p->T::m_ProFunc) (...)’
 98     // (p->*T::m_ProFunc)(a, b);  invalid use of non-static data member ‘T::m_ProFunc’
 99     // (p->T::*m_ProFunc)(a, b);  ‘m_ProFunc’ was not declared in this scope
100     // (p->*m_ProFunc)(a, b);  ‘m_ProFunc’ was not declared in this scope
101     return (p->*func)(a, b);
102 }
103 
104 /*External interface function,Encapsulate global or static member functions*/
105 int GResult(GFunc func, const int &a, const int &b)
106 {
107     printf("That's Ext GResult--->");
108     Add(a, b);
109     T::Add(a, b);
110 
111     return (*func)(a, b);
112 }
113 
114 int main(int argc, char *argv[])
115 {
116     printf("Program:Test pointer to funtion. Author by sciapex!\n");
117     int a = 1;
118     int b = 2;
119 
120     /* 1st way:general and static member funtion */
121     printf("Test 1st................!\n");
122     GFunc TFunc1 = Add;    //like as TFunc1 = &Add;
123     GFunc TFunc2 = &T::Add;
124 
125     TFunc1(a, b);
126     (*TFunc2)(a, b);       //like as (*TFunc1)(a, b);
127     (*TFunc2)(a, b);
128 
129     /* 2nd way:non-static member funtion */
130     printf("Test 2nd................!\n");
131     T Test1;
132 
133     //Test1.Result(&Test1.Max(), a, b);  error
134     //Test1.Result(&T::Min, a, b);    error
135     //Test1.Result(T::Min, a, b);     error
136     Test1.IResult(&T::Max, a, b);
137     Test1.IResult(&T::Min, a, b);
138 
139     Test1.Init(1);
140     Test1.IGetFunc(a, b);
141 
142     Test1.Init(2);
143     Test1.IGetFunc(a, b);
144 
145     // oparator class name
146     printf("2th:class name................!\n");
147     Test1.ISetFunc(&T::Max);
148     Test1.IGetFunc(a, b);
149 
150     // oparator non-member
151     printf("2nd:non-member................!\n");
152     Test1.m_ProFunc = &T::Min;
153     Test1.ISetFunc(Test1.m_ProFunc);
154     Test1.IGetFunc(a, b);
155 
156     T::SMFunc(&Test1, &T::Max, 100, b);
157     T::SMFunc(&Test1, &T::Min, 200, b);
158     T::SMFunc(&Test1, Test1.m_ProFunc, 300, b);
159     /* 3th way:external funtion */
160     printf("Test 3th................!\n");
161     T T1;
162 
163     //MResult(T1, T1.Max, a, b);  error
164     //MResult(&T1, T::Max, a, b); error
165     T1.Init(0);
166     MResult(&T1, &T::Max, a, b);
167     T1.Init(1);
168     MResult(&T1, &T::Min, a, b);
169     T1.Init(2);
170     MResult(&T1, T1.m_ProFunc, a, b);
171 
172     GResult(TFunc1, a, b);
173     GResult(TFunc2, a, b);
174 
175     printf("All Done!\n");
176     return (EXIT_SUCCESS);
177 }

Ubuntu输出

root@ubuntu:~/Test/test/
$ a.out
Program:Test pointer to funtion. Author by sciapex!
Test 1st................!
Add
static T::Add
static T::Add
Test 2nd................!
That's IResult:(0)--->T::Max
That's IResult:(0)--->T::Min
T::Max
T::Min
2th:class name................!
T::Max
2nd:non-member................!
T::Min
That's SMFunc(100:2)
T::Min
T::Max
That's SMFunc(200:100)
T::Min
T::Min
That's SMFunc(300:200)
T::Min
T::Min
Test 3th................!
unkown type
That's Ext MResult:(0)--->T::Min
T::Max
That's Ext MResult:(1)--->T::Min
T::Min
That's Ext MResult:(2)--->T::Min
T::Min
That's Ext GResult--->Add
static T::Add
Add
That's Ext GResult--->Add
static T::Add
static T::Add
All Done!

猜你喜欢

转载自www.cnblogs.com/sciapex/p/9303215.html