精华内容
下载资源
问答
  • 主要介绍了C++中回调函数及函数指针的实例详解的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
  • 主要介绍了C++ 中回调函数详解及简单实例的相关资料,需要的朋友可以参考下
  • 主要介绍了C++中回调函数(CallBack)的用法,较为详细的分析了C++中回调函数(CallBack)的原理并以实例形式总结了其具体用法,具有一定参考借鉴价值,需要的朋友可以参考下
  • 通过Qt控制台工程写了几个回调函数的例子,希望对初学者有帮助
  • 我在这篇文章对网上关于回调函数的使用进行了归纳总结,并且对每一种类型的回调函数都写了一个简单的例子来实现,每个例子都可以在vs2015编译通过,由于使用了C++11的新标准,所以在vc6.0可能没法直接编译通过...

    引言:
    在C++编程,尤其时写Qt程序时,需要大量使用回调函数,在网上也有很多大牛对回调函数的使用进行了讲解,但是很多都是针对某一个或者两个特定的类型的。我在这篇文章中对网上关于回调函数的使用进行了归纳总结,并且对每一种类型的回调函数都写了一个简单的例子来实现,每个例子都可以在vs2015中编译通过,由于使用了C++11的新标准,所以在vc6.0中可能没法直接编译通过。

    代码下载:https://download.csdn.net/download/wangjianbo09/12620100

    一、普通函数作为回调函数

    普通函数作为回调函数时,使用普通的函数指针进行传入。

    例:

    #include <iostream>
    using namespace std;
    typedef int (*pGeneralFun)(int, int);                // 定义函数指针
    int sum(int a, int b){
        return a+b;
    } 
    void result(pGeneralFun fun, int a, int b){      // 定义接口韩式,在接口函数内实现回调函数的调用
        cout<<(*fun)(a, b)<<endl;
    }
    void main(){
        result(sum, 1, 2);                // 普通函数的函数名即为指针
    }
    

    二、类的成员函数作为回调函数

    1、类的静态成员函数作为回调函数

    a、在类外定义接口函数

    #include <iostream>
    using namespace std;
    typedef int(*pGeneralFun)(int, int);     // 类的静态成员函数的函数指针与普通函数一致
    class Test{
    public:
        static int Max(int a, int b){
            return a>=b? a:b;
        }
    };
    void result(pGeneralFun fun, int a, int b){ // 类的静态成员函数的接口函数定义与普通函数一样
        cout<<(*fun)(a, b)<<endl;
    }
    void main(){
        result(Test::Max, 3, 4);        // 类的静态成员函数,类名::函数名 表示函数的地址
    }
    

    b、在类内定义接口函数

    #include <iostream>
    using namespace std;
    typedef int(*pGeneralFun)(int, int);      // 类的静态成员函数的函数指针与普通函数一致
    class Test{
    public:
        static int Max(int a, int b){
            return a>=b? a:b;
        }
        void result(pGeneralFun fun, int a, int b){    // 在类内部定义接口函数,定义形式与类外一样
            cout<<(*fun)(a, b)<<endl;
        }
    };
    void main(){
        Test test;
        test.result(Test::Max, 5, 6);           // 调用在类内定义的接口函数
    }
    

    c、在类A中定义回调函数,在类B中定义接口函数

    #include <iostream>
    using namespace std;
    typedef int (*pGeneralFun)(int, int);
    class A{
    public:
        static int Max(int a, int b){             // 在类 A 中定义回调函数
            return a>=b?a:b;
        }
    };
    class B{
    public:
        void result(pGeneralFun fun, int a, int b){
            cout<<(*fun)(a, b)<<endl;
        }
    };
    void main(){
        B b;
        A a;
        b.result(A::Max, 4, 5);
    }
    
    

    小结:

    当类内的成员函数为静态成员函数时,将该函数作为回调函数,使用的方式与普通函数基本上没有区别。只是当接口函数定义在类的内部时,调用接口函数要使用对象名。

    2、类的非静态成员函数作为回调函数

    a、在类外定义接口函数

    #include <iostream>
    using namespace std;
    class Test;                             // 在定义函数指针之前必须先声明类
    typedef int (Test::*pClassFun)(int, int);                         // 定义函数指针
    class Test{
    public:
        int sum(int a, int b){
        return a+b;
        }
    };
    void result(Test *test, pClassFun fun, int a, int b){       // 在定义接口函数时要传入一个对象
        cout<<(test->*fun)(a, b)<<endl;
    }
    void main(){
        Test test;
        result(&test, &Test::sum, 3, 4);               // 对于非静态成员,要使用&来创建指向成员的指针
    }

    b、在类内定义接口函数

    #include <iostream>
    using namespace std;
    class Test;
    typedef int(Test::*pClassFun)(int, int);
    class Test{
    public:
        int sum(int a, int b){
            return a+b;
        }
        void result(pClassFun fun, int a, int b){
            cout<<(this->*fun)(a, b)<<endl;               // 必须要用隐含的 this 指针来指向传入的函数
        }
    };
    void main(){
        Test test;
        test.result(&Test::sum, 3, 4);
    }
    

    c、在类 A 内定义回调函数,在类 B 内定义接口函数

    方式一:

    #include <iostream>
    using namespace std;
    class A;                  // 必须先声明类 A
    typedef int(A::*pClassFun)(int, int);
    class A{
    public:
        int sum(int a, int b){
            return a+b;
        }
    };
    class B{
    public:
        void result(A *test, pClassFun fun, int a, int b){
            cout<<(test->*fun)(a, b)<<endl;
        }
    };
    void main(){
        A a;
        B b;
        b.result(&a, &A::sum, 2, 3);
    }
    

    方式二:

    使用 stl 中的 function 和 bind

    #include <iostream>
    #include <functional>    // bind 的声明位于 头文件 functional 中
    using namespace std;
    using namespace std::placeholders;      // 占位符的定义位于命名空间 placeholder 中
     
    typedef function<int(int, int)>Fun;         // 定义的是一个函数模板,指针类型
     
    class B{
    public:
        void call(int a, Fun f) {               // 在类 B 中定义接口函数
            cout<<f(a, 2)<<endl;
        }
    };
    class A{
    public:
        int sum(int a, int b){
            return a+b;
        }
        void bind(){
            Fun fun = std::bind(&A::sum, this, _1, _2);    
            // 其中_1,_2为占位符,通过bind函数将this指针隐式结合在子函数的参数中
            // 这一步只能在类 A 中实现,因为this指针指的是由类A产生的对象
            B b;
            b.call(1, fun);               // 在类 A 中调用 B 中的接口函数
            // 调用接口函数的这一步如果要在主函数中实现,则可以使bind函数返回 fun,在主函数中
            // 使用b.call(1, a.bind())来进行调用
        }
    };
    int main(){
        A a;
        B b;
        a.bind();
        system("pause");
    }
    

    代码下载:https://download.csdn.net/download/wangjianbo09/12620100

    ————————————————
    版权声明:本文为CSDN博主「xhj_enen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/xhj_enen/article/details/83789038

    展开全文
  • 我在这篇文章对网上关于回调函数的使用进行了归纳总结,并且对每一种类型的回调函数都写了一个简单的例子来实现,每个例子都可以在vs2015编译通过。其中需要用到 bind和function的代码,由于使用了C++11的新标准...

    引言:

    在C++编程,尤其时写Qt程序时,需要大量使用回调函数,在网上也有很多大牛对回调函数的使用进行了讲解,但是很多都是针对某一个或者两个特定的类型的。我在这篇文章中对网上关于回调函数的使用进行了归纳总结,并且对每一种类型的回调函数都写了一个简单的例子来实现,每个例子都可以在vs2015中编译通过。其中需要用到 bind和function的代码,由于使用了C++11的新标准,所以在vc6.0中可能没法直接编译通过。

    一、普通函数作为回调函数

    普通函数作为回调函数时,使用普通的函数指针进行传入。

    例:

    #include <iostream>
    using namespace std;
    typedef int (*pGeneralFun)(int, int);                // 定义函数指针
    int sum(int a, int b){
        return a+b;
    } 
    void result(pGeneralFun fun, int a, int b){      // 定义接口韩式,在接口函数内实现回调函数的调用
        cout<<(*fun)(a, b)<<endl;
    }
    void main(){
        result(sum, 1, 2);                // 普通函数的函数名即为指针
    }

     

    二、类的成员函数作为回调函数

    1、类的静态成员函数作为回调函数

    a、在类外定义接口函数

    #include <iostream>
    using namespace std;
    typedef int(*pGeneralFun)(int, int);              // 类的静态成员函数的函数指针与普通函数一致
    class Test{
    public:
        static int Max(int a, int b){
            return a>=b? a:b;
        }
    };
    void result(pGeneralFun fun, int a, int b){    // 类的静态成员函数的接口函数定义与普通函数一样
        cout<<(*fun)(a, b)<<endl;
    }
    void main(){
        result(Test::Max, 3, 4);           // 类的静态成员函数,类名::函数名 表示函数的地址
    }

     

    b、在类内定义接口函数

    #include <iostream>
    using namespace std;
    typedef int(*pGeneralFun)(int, int);              // 类的静态成员函数的函数指针与普通函数一致
    class Test{
    public:
        static int Max(int a, int b){
            return a>=b? a:b;
        }
        void result(pGeneralFun fun, int a, int b){    // 在类内部定义接口函数,定义形式与类外一样
            cout<<(*fun)(a, b)<<endl;
        }
    };
    void main(){
        Test test;
        test.result(Test::Max, 5, 6);           // 调用在类内定义的接口函数
    }

     

    c、在类A中定义回调函数,在类B中定义接口函数

    #include <iostream>
    using namespace std;
    typedef int (*pGeneralFun)(int, int);
    class A{
    public:
        static int Max(int a, int b){             // 在类 A 中定义回调函数
            return a>=b?a:b;
        }
    };
    class B{
    public:
        void result(pGeneralFun fun, int a, int b){
            cout<<(*fun)(a, b)<<endl;
        }
    };
    void main(){
        B b;
        A a;
        b.result(A::Max, 4, 5);
    }

     

    小结:

    当类内的成员函数为静态成员函数时,将该函数作为回调函数,使用的方式与普通函数基本上没有区别。只是当接口函数定义在类的内部时,调用接口函数要使用对象名。

    2、类的非静态成员函数作为回调函数

    a、在类外定义接口函数

    #include <iostream>
    using namespace std;
    class Test;                             // 在定义函数指针之前必须先声明类
    typedef int (Test::*pClassFun)(int, int);                         // 定义函数指针
    class Test{
    public:
        int sum(int a, int b){
        return a+b;
        }
    };
    void result(Test *test, pClassFun fun, int a, int b){       // 在定义接口函数时要传入一个对象
        cout<<(test->*fun)(a, b)<<endl;
    }
    void main(){
        Test test;
        result(&test, &Test::sum, 3, 4);               // 对于非静态成员,要使用&来创建指向成员的指针
    }

     

    b、在类内定义接口函数

    #include <iostream>
    using namespace std;
    class Test;
    typedef int(Test::*pClassFun)(int, int);
    class Test{
    public:
        int sum(int a, int b){
            return a+b;
        }
        void result(pClassFun fun, int a, int b){
            cout<<(this->*fun)(a, b)<<endl;               // 必须要用隐含的 this 指针来指向传入的函数
        }
    };
    void main(){
        Test test;
        test.result(&Test::sum, 3, 4);
    }

     

    c、在类 A 内定义回调函数,在类 B 内定义接口函数

    方式一:

    #include <iostream>
    using namespace std;
    class A;                  // 必须先声明类 A
    typedef int(A::*pClassFun)(int, int);
    class A{
    public:
        int sum(int a, int b){
            return a+b;
        }
    };
    class B{
    public:
        void result(A *test, pClassFun fun, int a, int b){
            cout<<(test->*fun)(a, b)<<endl;
        }
    };
    void main(){
        A a;
        B b;
        b.result(&a, &A::sum, 2, 3);
    }

     

    方式二:

    使用 stl 中的 function 和 bind

    #include <iostream>
    #include <functional>    // bind 的声明位于 头文件 functional 中
    using namespace std;
    using namespace std::placeholder;      // 占位符的定义位于命名空间 placeholder 中
    
    typedef function<int(int, int)>Fun;         // 定义的是一个函数模板,指针类型
    
    class B{
    public:
        void call(int a, Fun f) {               // 在类 B 中定义接口函数
            cout<<f(a, 2)<<endl;
        }
    };
    class A{
    public:
        int sum(int a, int b){
            return a+b;
        }
        void bind(){
            Fun fun = std::bind(&A::sum, this, _1, _2);    
            // 其中_1,_2为占位符,通过bind函数将this指针隐式结合在子函数的参数中
            // 这一步只能在类 A 中实现,因为this指针指的是由类A产生的对象
            B b;
            b.call(1, fun);               // 在类 A 中调用 B 中的接口函数
            // 调用接口函数的这一步如果要在主函数中实现,则可以使bind函数返回 fun,在主函数中
            // 使用b.call(1, a.bind())来进行调用
        }
    };
    int main(){
        A a;
        B b;
        a.bind();
        system("pause");
    }
    

    展开全文
  • 回调函数,使用c++做的例子,适用于多线程领域
  • C++回调函数详解

    2015-07-31 13:50:43
    我们经常在C++设计时通过使用回调函数可以使有些应用(如定时器事件回调处理、用回调函数记录某操作进度等)变得非常方便和符合逻辑,那么它的内在机制如何呢,怎么定义呢?它和其它函数(比如钩子函数)有何不同呢?...
  • 一个Demo,描述了C#如何在C++中注册函数回调
  • C++中回调函数(CallBack)的使用

    万次阅读 2013-09-17 12:54:57
    如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过。 其错误是普通的C++成员函数都隐含了一个传递函数作为参数,亦即“this”指针,C++通过传递this指针给其成员函数从而实现程序函数可以...

    如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过。
    其错误是普通的C++成员函数都隐含了一个传
    递函数作为参数,亦即“this”指针,C++通过传递this指针给其成员函数从而实现成员函数可以访问C++的数据成员。这也可以理解为什么C++类的多个实例可以共享成员函数却-有不同的数据成员。由于this指针的作用,使得将一个CALL-BACK型的成员函数作为回调函数安装时就会因为隐含的this指针使得函数参数个数不匹配,从而导致回调函数安装失败。要解决这一问题的关键就是不让this指针起作用,通过采用以下两种典型技术可以解决在C++中使用回调函数所遇到的问题。这种方法具有通用性,适合于任何C++。   
       
      1).   不使用成员函数,为了访问类的成员变量,可以使用友元操作符(friend),在C++中将该函数说明为类的友元即可。      
      2).   使用静态成员函数,静态成员函数不使用this指针作为隐含参数,这样就可以作为回调函数了。静态成员函数具有两大特点:其一,可以
    在没有类实例的情况下使用;其二,只能访问静态成员变量和静态成员函数,不能访问非静态成员变量和非静态成员函数。由于在C++中使用类成员函数作为回调函数的目的就是为了访问所有的成员变量和成员函数,如果做不到这一点将不具有实际意义。解决的办法也很简单,就是使用一个静态类指针作为类成员,通过在类创建时初始化该静态指针,如pThis=this,然后在回调函数中通过该静态指针就可以访问所有成员变量和成员函数了。

    这种处理办法适用于只有一个类实例的情况,因为多个类实例将共享静态类成员和静态成员函数,这就导致静态指针指向最后创建的类实例。为了避免这种情况,可以使用回调函数的一个参数来传递this指针,从而实现数据成员共享。这种方法稍稍麻烦,这里就不再赘述。关于静态方法访问非静态变量和函数的方式请见http://www.cnblogs.com/this-543273659/archive/2011/08/29/2157966.html

    首先明白什么是回调函数:比如说被调函数void callbackf(int n){}要想作为回调函数的话,callbackf必须作为主调函数的形参出现,如void f(void (*p(int)),int n)形式才行!

    如果我要在static中调用类中的成员,怎么做?
    我得定义一个全局的 指向该类的指针,然后在类的初始化函数里面将 类的this 指针赋值给该全局指针。
    然后在static函数中通过该全局指针调用类的其它成员。

    例子1:

    复制代码
    #include "stdafx.h"
    #include <iostream>
    #include <assert.h>
    using namespace std;
    
    class Test
    {
    public:
    
        friend void callBackFun(void){ cout << "CallBack Function!";} //友元函数作为回调函数 friend方式实现,											  //因为callBackFun默认有一个const Test* 的指针
    };
    
    typedef void (*FPtr)(void);
    
    void Fun(FPtr ptr)
    {
        ptr();
    }
    
    
    
    int main(void)
    {
        Fun(callBackFun); 
    
        return 0;
    }

    例2:

    #include<iostream> using namespace std; class A { public:    static void callback()  //类的成员函数作为回调函数 static方式实现  {   cout<<"回调函数开始执行了!"<<endl;  } }; void f(void (*p)())  {   p();

     } int main() {  void (*p)();  p=A::callback;  f(p);  return 0; }

    还可以把f()函数设为类的成员函数:

    #include<iostream> using namespace std; class A { public:    static void callback()  //类的成员函数作为回调函数 static方式实现  {   cout<<"回调函数开始执行了!"<<endl;  }  void f(void (*p)())  {   p();

     } };

    int main() {  A a;  void (*p)();  p=A::callback;  a.f(p);  return 0; }

    ///什么是回调函数
      
    回调函数就是那些自己写的,但是不是自己来调,而是给别人来调用的函数。
    消息响应函数就可以看成是回调函数,因为是让系统在合适的时候去调用。这不过消息响应函数就是为了处理消息的,所以就拿出来单做一类了。其实本质上就是回调函数。
    但是回调函数不是只有消息响应函数一种,比如在内核编程中,驱动程序就要提供一些回调函数,当一个设备的数据读写完成后,让系统调用这些回调函数来执行一些后续工作。回调函数赋予程序员这样一种能力,让自己编写的代码能够跳出正常的程序控制流,适应具体的运行环境在正确的时间执行。
    
       
    普通的函数是:咱们的函数调用系统的函数,
    
    把你写的程序和系统已经封装好的函数看成两个部分
    你的程序使用系统的函数 那叫 调用
    系统函数使用你的程序函数 就叫回调
    一般多用于系统函数与你的函数要进行异步处理
    比如按键事件,其实是个消息
    你的函数比按键事件更早存在
    所以你要将这个函数做为回调函数提交给系统,
    然后系统在接收到按键事件后,再调用你的函数
    /
    比如:void fun(){printf();}
    而回调函数是:系统调用你的函数。
    win32 编程的WndProc,java的事件,c#的delegate都是这种思想。可以说没有坏处,回调使得系统更加灵活。
    函数指针做为函数的参数,传递给一个被调用函数,
    被调用函数就可以通过这个指针调用外部的函数,这就形成了回调
    
    一般的程序中回调函数作用不是非常明显,可以不使用这种形式
    
    最主要的用途就是当函数不处在同一个文件当中,比如动态库,要调用
    其他程序中的函数就只有采用回调的形式
    
    #include "stdio.h"
    #include "conio.h"
    
    int add(int a, int b);
    int libfun(int (*pDis)(int a, int b));
    
    int main(void)
    {
    int (*pfun)(int a, int b);
    
    pfun = add;
    libfun(pfun);//调用int libfun(int (*pDis)(int a, int b))
    
    
    }
    
    int add(int a, int b)
    {
    return a + b;
    
    }
    
    int libfun(int (*pDis)(int a, int b))//回调add()函数
    {
    int a, b;
    a = 1;
    b = 2;
    printf("%d", pDis(a, b));
    
    }
    
    现在这几个函数是在同一个文件当中
    
    假如 
    int libfun(int (*pDis)(int a, int b))
    是一个库中的函数,就只有使用回调了,通过函数指针参数将外部函数地址传入
    来实现调用
    
    函数 add 的代码作了修改,也不必改动库的代码,就可以正常实现调用
    便于程序的维护和升级
    
    展开全文
  • C++中回调函数的一个简单例子?

    万次阅读 多人点赞 2016-01-08 14:13:57
    注意:在这个类指定了回调函数回调函数的执行者,和回调函数指针 重要的是  回调函数回调函数指针是怎么关联的? 2、Person类的具体实现(Person.cpp) 上面的Person.cpp文件的实现当中,我...

    回调函数应用实例:

    1、定义一个Person类 (Person.h)文件:

    注意:在这个类中指定了回调函数,回调函数的执行者,和回调函数指针

    重要的是  回调函数回调函数指针是怎么关联的?

    2、Person类的具体实现(Person.cpp)

    上面的Person.cpp文件的实现当中,我运用了枚举的使用,请一定要注意,回调函数指针指向的是哪一个回调函数,回调函数的执行者是谁。必须要有,否则不能成功!


    3、在main函数中的调用情况:


    我圈起来的这个函数的作用:

    1、明确 回调函数指针  所指向的 回调函数 是谁;

    2、明确 回调函数指针 的 执行者 是谁;


    有一点我必须要说清:因为有一篇文章中我这点说的模糊,现在澄清;

    这里为什么要加‘&’符号呢?我们不是常说 “一个函数的名称” 就代表这个 一个函数的“执行地址,或者函数指针”吗?

    在全局函数的情况下,这种情况是正确的。我截个图:

    但是在类中的非静态成员函数,不带&符号(取函数的地址)编译时通不过。

    如果是类中的静态成员函数也可以通过



    所以说,类中的非静态成员函数,【&函数名!=函数名】。取得函数的地址,就要加上&符号。


    这里加‘*’号,是和前面加'&'符号相对的,也就是取得这个具体的函数对象。【这里说的模糊,但是这就是区别呀!】


    这些内容代表我个人的观点,希望大家看到的能够多多指正,不要放过错误,这才是最重要的! 如果大家能够给出观点,我将会非常的感激!


    展开全文
  • c++回调函数应用,在通信编程可能会使用的几率大一下,使用时现将函数调用的地址保存下来,然后在使用时直接调用之前保存的函数地址,即为回调
  • c++类成员函数作为回调函数
  • c++ qt 中在静态函数中发信号的方式,以及回调函数的基本使用
  • C++回调函数

    2014-04-02 11:26:17
    C++中如何处理编写回调函数,什么是回调函数
  • C++将类的成员函数作为回调函数使用介绍
  • 2.回调函数 什么是回调函数呢?回调函数其实就是一个通过函数指针调用的函数!假如你把A函数的指针当作参数传给B函数,然后在B函数中通过A函数传进来的这个指针调用A函数,这就是回调机制。B函数就是回调函数。 3....
  • 附件是一套C#调用C++dll时,实现回调函数的Demo程序。亲测可用。
  • 浅谈C++回调函数

    千次阅读 2018-02-28 22:09:30
    1.什么是回调函数? 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数回调函数不是由该函数的实现方...
  • C# Csharp 调用 C++的DLL回调函数

    热门讨论 2014-03-21 13:50:40
    一个是C++的DLL以及源码 一个是调用他的C#源码 都是VS2010编译测试通过
  • C++学习:回调函数(callback)

    万次阅读 多人点赞 2017-07-09 12:36:54
    C++学习:回调函数(callback)简介: 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数回调...
  • C++回调函数使用心得

    万次阅读 多人点赞 2018-11-11 15:23:52
    C++回调函数使用心得前言回调函数也是普通函数C回调函数C++回调函数使用场景描述C++回调函数定义静态成员函数访问非静态成员函数的方法回调对象更复杂的讨论 前言 关于C++回调函数的介绍网上有很多,要知道它的...
  • C++实现回调函数

    2020-09-04 18:52:47
    回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数回调函数不是由该函数的实现方直接调用,而是在特定...
  • 易语言实现 c++dll的消息回调函数

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 111,352
精华内容 44,540
关键字:

c++中回调函数

c++ 订阅