C++ 异步回调

上一文中讲了C语言通过函数指针实现异步回调

本文继续讨论C++中实现回调,由于C++中有类,而C语言中的回调函数不能直接定义为成员函数,所以就很麻烦了,下面将讨论解决办法。

首先知道静态成员函数是全局的,也就是类的,因此推测可以用静态成员函数来实现回调机制。这里补充一下关于类中静态成员的知识

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

class xiabo_C{
public:
    xiabo_C():a(10),d(8)
    {
        printf("I am xiabo_C() function\n");
    }
    static int sfunc(); //静态成员函数也遵循public,private,protected访问规则
    int func(void);

public:
    int a;
    static int b ;      //此处不能初始化
    static const int c = 9;//只有静态常量才能直接初始化
    const  int d;
};

int  xiabo_C::b = 11;   //静态成员变量的初始化只能这样,不能在构造中初始化

int xiabo_C::sfunc(){   //!!!静态成员函数在类外部实现时,千万不要加static,不要写成了static int sfunc(){},这是内外部的静态C函数
    //xiabo::a = 11;    //error   静态成员函数不能应用非静态成员
    xiabo_C::b = 12;
    printf("I am static member function,b = %d\n",xiabo_C::b );
    return 0;
}
static int sfunc1(){
    printf("I am static function, not member function \n" );
    return 0;
}
int xiabo_C::func(void){
    xiabo_C::b = 12;
    xiabo_C::sfunc();
    sfunc1();
    return 0;
}
int main(void ){
    xiabo_C xiabo;
    xiabo.func();
    xiabo_C::sfunc();  //静态成员函数是类的,不是某个对象的,引用必须通过类名来访问
    getchar();
    return 0;
}

下面就使用静态成员函数实现回调,同样的和C语言中一样的结构,只不过改成类

//-------------
class xiabo2_C{
public:
    typedef int (*pcb)(int a);
    typedef struct parameter{
        int a ;
        pcb callback;
    }parameter;
    xiabo2_C():m_a(1){

    }
    //普通函数
    void GetCallBack(parameter* p)  // 写回调者实现的回调函数
    {
        m_a = 2;
        //do something
        while(1)
        {
            printf("GetCallBack print! \n");
            _sleep(2000);
            p->callback(p->a);
        }
    }
    int SetCallBackFun(int a, pcb callback)
    {
        printf("SetCallBackFun print! \n");
        parameter *p = new parameter ;
        p->a  = 10;
        p->callback = callback;
        GetCallBack(p);
        return 0;
    }

public:
    int m_a;
};

class xiabo2Test_C{
public:
    xiabo2Test_C():m_b(1){

    }
    static int fCallBack(int a)         // 应用者实现的回调函数,静态成员函数,但是不能访问类中非静态成员了,破坏了类的结构
    {
        //do something
        //m_b = a;      // 不能访问类中非静态成员了,破坏了类的结构,应用者使用很麻烦
        printf("a = %d\n",a);
        printf("fCallBack print! \n");
        return 0;
    }
public:
    int m_b;
};
int main(void ){
    //test_statichunc();
    xiabo2_C xiabo2;
    xiabo2.SetCallBackFun(5,xiabo2Test_C::fCallBack);
    getchar();
    return 0;
}

虽然这种方法实现了回调,但是应用者那是1万个不情愿,尼玛为了用个回调,我类类里面的非静态成员什么都不能用了,还不如不回调呢,让我直接调用吧。那有没有一种方法两全其美呢,有!那是必须的。

//-------------------
template<typename Tobject,typename Tparam>
class xiabo3_C{
    typedef void (Tobject::*Cbfun)(Tparam* );
public:
    bool Exec(Tparam* pParam);
    void Set(Tobject *pInstance,Cbfun pFun,Tparam* pParam);

private:
    Cbfun pCbfun;
    Tobject* m_pInstance;
};

template<typename Tobject,typename Tparam>
void xiabo3_C<Tobject,Tparam>::Set(Tobject *pInstance,Cbfun pFun,Tparam* pParam){
    printf("Set print!\n");
    m_pInstance = pInstance;
    (pInstance->*pFun)(pParam);     //可以直接在这里回调传过来的函数指针
    pCbfun = pFun;
}
template<typename Tobject,typename Tparam>
bool xiabo3_C<Tobject,Tparam>::Exec(Tparam* pParam){
    printf("Exec print!\n");
    (m_pInstance->*pCbfun)(pParam);//也可以在这里回调传过来的函数指针
    return true;
}

class xiabo3Test_C{
public:
    xiabo3Test_C():m_N(13){

    }
    void fCallBack(int *p){
        printf("fCallBack : Sum = m_N + *p = %d\n",*p + m_N);
        printf("fCallBack print! I am a member function! I can access all the member ,HaHa\n");
    }

private:
    int m_N;
};
int main(void ){
    xiabo3_C<xiabo3Test_C,int> xiabo3;
    xiabo3Test_C xiabo3Test;
    int p = 13;
    xiabo3.Set(&xiabo3Test,&xiabo3Test_C::fCallBack,&p); //
    xiabo3.Exec(&p);
    getchar();
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 07:49:44

C++ 异步回调的相关文章

C#的异步回调函数

关于C#的异步回调,在ActionScript 3.0当中 , 有关键字Function , 可以直接传class函数为回调函数.但是在C#当中,需要使用到委托,其中应用的最多的当属 : Action / Func .当然你可以使用关键字delegate来自定义委托.这里翼Action /  Func为例来讲解C#的异步回调,如果不了解C#的委托机制,需要自己先百度/Google一下,再来看这篇博客. BeginInvoke 方法用于启动异步调用.它与您需要异步执行的方法具有相同的参数,只不过还

嵌套的异步回调

今天被一个问题纠结了2个小时,一开始失败的代码大概是这样的: dispatch_group_t group = dispatch_group_create(); while([rs next]){ dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ [httpHelper getSecure:url completionHandler:^(NSDictionary* dict){ // 子任务 }]; }); } dis

java 中的异步回调

异步回调,本来在c#中是一件极为简单和优雅的事情,想不到在java的世界里,却如此烦琐,先看下类图: 先定义了一个CallBackTask,做为外层的面子工程,其主要工作为start 开始一个异步操作,然而真正干活的是CallBackBody,它里面的execute才是真正要处理的事情,如果成功,则触发onSucess,否则触发onFailure. CallBackApp做为最终的运行舞台,这里面还得单独跑一个线程,来启动CallBackTask,这样才不会阻塞后面的处理. CallBackBo

AFHTTPClient的异步回调模式

以前第一个版本,ios的http都用的同步模式,在很多地方会导致线程阻塞,自己开发了一个简易的AFHTTPClient的异步回调模式. 回调的protocol: @protocol MyAFNetworkingResponse <NSObject> @required -(void) MyHttpResponse:(NSString*)ret Type:(NSString*)strType returnData:(NSObject*)retData; @end AFHTTPClient的异步通

用tornado 写异步回调程序

用tornado,一般都用到它的 AsyncHTTPClient的 fetch.我们可以参考 fetch,使用tornado的特性,写异步回调程序 首先看看 fetch的实现,关键是用了future def fetch(self, request, callback=None, **kwargs): """Executes a request, asynchronously returning an `HTTPResponse`. The request may be eit

jquery.Deferred promise解决异步回调

我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越深,代码可读性就会越差. $.ajax({ url: url, data: dataObject, success: function(){ console.log("I depend on ajax result."); }, error: function(){} }); consol

性能优化之——.NET(C#)调用webService获取客户端IP地址所属区域(异步回调)(二)

朋友们这次分享的是异步回调不是异步调用哦! 请注意喽! 功能描述,接口地址,方法名称以及参数说明,同上篇:.NET(C#)调用webService获取客户端IP地址所属区域(非异步)(一)(LZ比较懒,不想写太多哦!(⊙0⊙)) 实现代码如下: 1 namespace main 2 { 3 class Program 4 { 5 public static string Result = string.Empty; 6 7 static void Main(string[] args) 8 {

State Threads——异步回调的线性实现

State Threads——异步回调的线性实现 原文链接:http://coolshell.cn/articles/12012.html 本文的标题看起来有点拗口,其实State Threads库就是在单线程中使用同步编程思想来实现异步的处理流程,从而实现单线程能并发处理成百上千个请求,而且每个请求的处理过程是线性的,没有使用晦涩难懂的callback机制来衔接处理流程. ST (State Threads) 库提供了一种高性能.可扩展服务器(比如web server.proxy server

同步、异步、异步回调

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Runtime.Remoting.Messaging; namespace Async { public delegate int AddHandler(int a, int b); public class AddCls { public static

从一个nodejs爬虫来看nodejs异步回调嵌套时数据的安全性[原创,未经授权禁止转载]

代码如下: /** * Created by Totooria Hyperion on 2016/4/20. */ 'use strict'; const fs = require('fs');const path = require('path');const cheerio = require('cheerio');const request = require('request'); function getCategoryByUrl(url,callback){ request(url,