函数指针--全局函数指针与类的函数指针(二)
程序员文章站
2022-04-04 09:28:49
本次对之前的说明做个补充,大体内容还是一样的 这里对类里面的成员函数指针变量的使用继续进行了解,最主要的是希望能达到通过非静态成员指针变量来引用各自的非静态成员函数。 这样每个实例可以保存当前对象对应的功能操作,而无需再进行一些业务逻辑或者算法的计算,提高运行效率。 定义一个函数指针typedef ......
本次对之前的说明做个补充,大体内容还是一样的
这里对类里面的成员函数指针变量的使用继续进行了解,最主要的是希望能达到通过非静态成员指针变量来引用各自的非静态成员函数。
这样每个实例可以保存当前对象对应的功能操作,而无需再进行一些业务逻辑或者算法的计算,提高运行效率。
定义一个函数指针typedef int (T::*MFunc)(const int &, const int &);
在类T里面声明一个公有的非静态成员函数指针变量MFunc m_ProFunc;
1. 在类的非静态成员函数里面可以通过this指针对该成员变量进行操作(this->*m_ProFunc)(a, b);
2. 在类的静态成员函数和外部接口函数没有this指针,则无法通过该方式进行操作m_ProFunc。当你尝试使用实例对象进行操作时,例如给一个实例的形参T* t; 然后在函数里面通过指针操作该类(t->*m_ProFunc)(a, b);就无法通过编译,因为编译器无法正确识别该表达式。是的,(t->*T::m_ProFunc)(a, b)和(t->T::*m_ProFunc)(a, b)这种方式在静态成员函数或外部接口函数都无法使用。
通过调测,发现了可以使用形参的方式来让编译器识别实例对象的非静态成员函数指针变量所调用的功能,这实在让人开心,因为这样就可以实现设计要求。
这样将函数指针变量当做实参传给调用的接口,继而在接口里面进行实际的功能调用。
注意:因为使用了指针变量,这就需要对非静态成员函数指针形参进行非空校验,避免程序coredump。
综上所述,对之前的代码进行了调整,希望可以提供一定的帮助和参考:)
/* Author by sciapex@gmail.com */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> int Add(const int &a, const int &b){ printf("Add\n"); return a + b;}; int Max(const int &a, const int &b){ printf("Max\n"); return a > b ? a : b;}; int Min(const int &a, const int &b){ printf("Min\n"); return a < b ? a : b;}; class T; /*Pointer to non-static member function*/ typedef int (T::*MFunc)(const int &, const int &); /*Pointer to global function*/ typedef int (*GFunc)(const int &, const int &); class T { public: int m_Id; MFunc m_ProFunc; static MFunc m_sProFunc; public: T(): m_Id(0), m_ProFunc(NULL) {}; int Max(const int &a, const int &b) {printf("T::Max\n");return a > b ? a : b;}; int Min(const int &a, const int &b) {printf("T::Min\n");return a < b ? a : b;}; static int Add(const int &a, const int &b) {printf("static T::Add\n");return a + b;}; static int SMFunc(T *t, MFunc func, const int &a, const int &b) { if (t == NULL) { printf("Object is null!\n"); return -1; } if (func == NULL) { printf("MFunc is null!\n"); return -1; } printf("That's SMFunc(%d:%d)\n", a, t->m_Id); t->m_Id = a; t->Min(a, b); //(t->*m_ProFunc)(a, b); //error invalid use of member ‘T::m_ProFunc’ in static member function (t->*func)(a, b); //ok return t->m_Id; }; int Init(const int &type) { m_Id = type; if (type == 1) { m_ProFunc = &T::Max; } else if (type == 2) { //m_ProFunc = &(this->Min); // error m_ProFunc = &T::Min; } else { printf("unkown type\n"); return -1; } return 0; } /*Internal interface function,Encapsulate non-static member functions*/ int IResult(MFunc func, const int &a, const int &b){ printf("That's IResult:(%d)--->", m_Id); return (this->*func)(a, b); } int Run(const int &a, const int &b) { //(*m_ProFunc)(a, b); // error:invalid use of unary ‘*’ on pointer to member (this->*m_ProFunc)(a, b); // ok } }; MFunc T::m_sProFunc = &T::Min; /*External interface function,Encapsulate non-static member functions*/ int MResult(T* p, MFunc func, const int &a, const int &b) { printf("That's Ext MResult:(%d)--->", p->m_Id); p->Min(a, b); if (func == NULL) { printf("Pointer is null!\n"); return -1; } // *(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) (...)’ // (p->*T::m_ProFunc)(a, b); invalid use of non-static data member ‘T::m_ProFunc’ // (p->T::*m_ProFunc)(a, b); ‘m_ProFunc’ was not declared in this scope // (p->*m_ProFunc)(a, b); ‘m_ProFunc’ was not declared in this scope return (p->*func)(a, b); } /*External interface function,Encapsulate global or static member functions*/ int GResult(GFunc func, const int &a, const int &b) { printf("That's Ext GResult--->"); Add(a, b); T::Add(a, b); return (*func)(a, b); } int main(int argc, char *argv[]) { printf("Program:Test pointer to funtion. Author by sciapex!\n"); int a = 1; int b = 2; /* 1st way:general and static member funtion */ printf("Test 1st................!\n"); GFunc TFunc1 = Add; //like as TFunc1 = &Add; GFunc TFunc2 = &T::Add; TFunc1(a, b); (*TFunc2)(a, b); //like as (*TFunc1)(a, b); (*TFunc2)(a, b); /* 2nd way:non-static member funtion */ printf("Test 2nd................!\n"); T Test1; //Test1.Result(&Test1.Max(), a, b); error //Test1.Result(&T::Min, a, b); error //Test1.Result(T::Min, a, b); error Test1.IResult(&T::Max, a, b); Test1.IResult(&T::Min, a, b); Test1.Init(1); Test1.Run(a, b); Test1.Init(2); Test1.Run(a, b); T::SMFunc(&Test1, &T::Max, 100, b); T::SMFunc(&Test1, &T::Min, 200, b); T::SMFunc(&Test1, Test1.m_ProFunc, 300, b); /* 3th way:external funtion */ printf("Test 3th................!\n"); T T1; //MResult(T1, T1.Max, a, b); error //MResult(&T1, T::Max, a, b); error T1.Init(0); MResult(&T1, &T::Max, a, b); T1.Init(1); MResult(&T1, &T::Min, a, b); T1.Init(2); MResult(&T1, T1.m_ProFunc, a, b); GResult(TFunc1, a, b); GResult(TFunc2, a, b); printf("All Done!\n"); return (EXIT_SUCCESS); }
输出
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 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!
推荐阅读
-
C++指针与数组、函数、动态内存分配
-
c++ 拷贝构造函数(重点在内含指针的浅拷贝和深拷贝)
-
约瑟夫环问题的PHP实现 使用PHP数组内部指针操作函数
-
C++入门之new和delete关键字、静态成员属性与函数、this指针使用介绍
-
返回指针的函数
-
php数组函数序列之end() - 移动数组内部指针到最后一个元素,并返回该元素的值
-
php数组函数序列之each() - 获取数组当前内部指针所指向元素的键名和键值,并将指针移到下一位
-
php数组函数序列之prev() - 移动数组内部指针到上一个元素的位置,并返回该元素值
-
函数传参过程中的数据跑飞(指针)
-
php数组函数序列之next() - 移动数组内部指针到下一个元素的位置,并返回该元素值