实现类成员函数回调

一、采用tri::function/bind方法实现类成员函数内部调用

首先声明函数类型

1 std::tr1::function<double(double)> func;

在需要调用函数的地方绑定函数


 1 switch (flgFun) {
2 case flgSine:
3 func = std::tr1::bind(&CAnalog::Sin, this, std::tr1::placeholders::_1);
4 break;
5 case flgSquare:
6 func = std::tr1::bind(&CAnalog::Square, this, std::tr1::placeholders::_1);
7 break;
8 case flgRamp:
9 func = std::tr1::bind(&CAnalog::Ramp, this, std::tr1::placeholders::_1);
10 break;
11 default:
12 break;
13 }

参考后面完整代码,需要包含头文件functional

其实刚开始就是按照自己的想法去解决问题,回过来想想能用到这种方法很可能就是自己的设计模式不够好,天天研究这种感觉山寨的方法真不如去多研究设计模式,软件框架设计是软件健壮的根本那。

二、刚开始找了一种方法是函数指针强制转换,使用方法:

1 typedef void* (*FUNC)(void*);           //定义FUNC类型是一个指向函数的指针
2 FUNC callback = (FUNC)&MyClass::func; //强制转换func()的类型

参考:C++中类成员函数作为回调函数

尝试了一下不行,论坛里面有这样解释:为了实现回调,我们必须把this指针给转换掉
!可为了在该函数中可以直接操作该类中的成员,我们必须保留this指针 !所 以这是矛盾的,通过转换指针的手段是不能达到 目的的 !

三、还有查到一种方法是回调代理类,感觉比较麻烦也没有尝试,这里给出链接:C++实现把非静态成员函数作为回调函数(非static)

完整代码参考:


 1 enum flgFun{
2 flgSine = 100,
3 flgSquare,
4 flgRamp,
5 };
6 CMath {
7 double Square(double x);
8 double Ramp(double x);
9 double Sin(double x);
10 //求积分,flgFun为自定义函数标志,为enum型
11 double Integral(int flgFun, double a, double b, double Omg);
12 }
13 double CMath::Integral(int flgFun, double a, double b, double Omg)
14 {
15 std::tr1::function<double(double)> func;
16 switch (flgFun) {
17 case flgSine:
18 func = std::tr1::bind(&CAnalog::Sin, this, std::tr1::placeholders::_1);
19 break;
20 case flgSquare:
21 func = std::tr1::bind(&CAnalog::Square, this, std::tr1::placeholders::_1);
22 break;
23 case flgRamp:
24 func = std::tr1::bind(&CAnalog::Ramp, this, std::tr1::placeholders::_1);
25 break;
26 default:
27 break;
28 }
29 double sum,step,result;
30 const int n = 200; // 统一固定积分步长为200
31 sum = (func(Omg*a)+func(Omg*b))/2;
32 step = (b-a)/n;
33 for (int i=1;i<n;i++) {
34 sum += func((a+i*step)*Omg);
35 }
36 result = sum*step;
37 return result;
38 }

时间: 2024-10-31 20:22:18

实现类成员函数回调的相关文章

类成员函数可以为回调函数吗

关于类成员函数是否可以成为回调函数,我们首先需要明确几个定义,1. 什么是回调函数 2. 为什么要使用回调函数 3. 调用普通类成员函数和调用回调函数有什么区别 什么是回调函数? 简而言之,回调函数就是一个通过函数指针调用的函数,如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数 为什么要使用回调函数? 因为可以把调用者与被调用者分开.调用者不关心谁是被调用者,所有它需知道的,只是存在一个具有某种特定原型.某些限制条件(如返回值为int

理解ATL中的一些汇编代码(通过Thunk技术来调用类成员函数)

我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以拿来学习应该是很方便的.但是因为ATL的代码充满了模板和宏,内部还夹杂着汇编,所以如果没有比较丰富的C++模板和系统底层的知识,一般人会看得一头雾水. 下面我们主要分析一下ATL中的一些汇编代码. ATL中出现汇编代码主要是2处,一处是通过Thunk技术来调用类成员函数处理消息:还有一处是通过打开_

类成员函数的指针与多态性

1 类成员函数的指针 2 类成员函数的指针数组 3 指向类成员函数的指针的指针 1 类成员函数的指针 auto func1 = &com::jia;//C++函数指针 int (com::*p)(int, int) = &com::jia;//C函数指针 1 #include <iostream> 2 3 class com 4 { 5 private: 6 int a; 7 int b; 8 public: 9 com(int x, int y) :a(x), b(y) 10

C++ 获取类成员函数地址方法 浅析

C语言中可以用函数地址直接调用函数: void print () { printf ("function print"); } typdef void (*fun)(); fun f = print; f(); C++中类非静态成员函数必须通过实例去调用,C++中类成员函数调用: class test { public: void print () { printf ("function print"); } }; 我们同样可以通过定义函数指针来调用如下: type

C++的const类成员函数

转自:http://blog.csdn.net/lihao21/article/details/8634876 我们知道,在C++中,若一个变量声明为const类型,则试图修改该变量的值的操作都被视编译错误.例如, [cpp] view plain copy const char blank = ''; blank = '\n';  // 错误 面向对象程序设计中,为了体现封装性,通常不允许直接修改类对象的数据成员.若要修改类对象,应调用公有成员函数来完成.为了保证const对象的常量性,编译器

C++:类成员函数的重载、覆盖和隐藏区别?

#include <iostream> class A { public: void func() { std::cout << "Hello" << std::endl; } void func(int k) { } }; class B : public A { public: using A::func; // 把这句注释掉试试,嘿嘿 void func(int i) { } }; int main() { B b; b.func();//编译

一个类成员函数的局部静态变量问题

之前工作中遇到一个问题,就像题目中描述的那样,看起来题目有些拗口复杂,这里解释下,当时遇到的需求需要这样处理:调用某个类对象的某个成员函数时,第一次有具体意义的,其他时候都是保持不变的.无意义的.这个需求可以看做是在调用某成员函数时,第一次进行初始化,其他时候不进行操作,即在首次调用时进行初始化,根据这点,很容易想到c/c++里面的static变量,它的作用是保持变量内容的持久,存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化.根据需求,使用static局部变量,写下

【非原创】C++类成员函数的重载、覆盖和隐藏

链接:https://www.nowcoder.com/questionTerminal/266d3a6d4f1b436aabf1eff3156fed95来源:牛客网 题目:类成员函数的重载.覆盖和隐藏区别描述正确的有? A.覆盖是指在同一个类中名字相同,参数不同 B.重载是指派生类函数覆盖基类函数,函数相同,参数相同,基类函数必须有virtual关键字 C.派生类函数与基类函数相同,但是参数不同,会"隐藏"父类函数 D.函数名字相同,参数相同,基类无virtual关键字的派生类的函数

【转】C++的const类成员函数

我们知道,在C++中,若一个变量声明为const类型,则试图修改该变量的值的操作都被视编译错误.例如, const char blank=' '; blank='\n'; //错误 面向对象程序设计中,为了体现封装性,通常不允许直接修改类对象的数据成员.若要修改类对象,应调用公有成员函数来完成.为了保证const对象的常量性,编译器须区分不安全与安全的成员函数(即区分试图修改类对象与不修改类对象的函数).例如, const Screen blankScreen;  //Screen为class,