C++中利用回调实现消息通知

本文介绍了回调函数的概念及其在消息通知中的应用。通过一个具体的C++示例详细讲解了如何利用回调函数实现任务间的异步通信,特别是如何通过传递函数指针来实现这一目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  回调函数实现消息通知,例如交派一个任务给某人去做,然后不去管他怎样做,什么时候做,做得怎样,而等他完成后自己汇报。这就是我对回调的理解,当然其中还有涉及了异步处理的思想;首先是函数A去调用一个函数B(相当于给人指派任务),B函数的生命周期不可知,函数A无需等待它完成而可以去处理其它的任务;那么当B函数完成了(或者需要反馈信息)时,如何返回?因为函数A没有在等待B返回,已经去处理别的任务。这个时候就需要函数B主动去调用别的函数C来实现信息的返回,这里的C函数与A函数是共享资源的,例如共同拥有一个文本框资源,那么C函数就可以改变文本框的输出。关键的地方是,A函数调用B函数时需要把C函数传给B函数,相当于A告诉B,C是我的接口人,有问题找C就行。当然,什么时候找C是由B决定的。


  回调函数其实就是把一个函数的指针作为参数传送出去,它的目的是为了让被调函数根据需求来调用这个传递下去的函数。在程序开发中,有些代码往往是不允许被修改的,例如一些库文件,如果想增加一些功能或者增加一些处理,那么就可以通过回调函数来实现,因为该函数的代码实现是可以自由编写的。当然,库文件里面要预留有这种回调的接口。


  其中,消息通知是回调中的一种。一般回调函数都是全局函数,由于C++类的封装性,要访问类成员需先实例对象,或者类成员定义成static属性,又或者定义回调函数为类的友元函数。要在C++中实现消息通知,那就必须能对类的成员进行访问,所以最好是用类的成员函数作为回调函数。可是,类的成员函数隐含了该类的属性,回调函数只能定义成static属性才能使用,但static属性的函数只能访问static属性的函数及变量,那就无法达到随意访问类成员的效果。经过反复了解及验证,暂时较好的实现方式是传递this指针,这样可以所操作的对象是相同的,那么资源就是相同的。

第一次写博客,作为技术菜鸟知识面不够宽,错漏的地方将不断修正!



//ClassA.h文件
#pragma once

#include "ClassB.h"

class ClassA
{
public:
	ClassA();
	~ClassA();

	int nStart();
	int nCallBack(char *p);

private:
	ClassB *myClassB;

public:
	char *ch;
};


//ClassA.cpp文件
#include "stdafx.h"
#include "ClassA.h"

ClassA::ClassA()
{
	myClassB = new ClassB();
	ch = "abc";
	nStart();
	
}

ClassA::~ClassA()
{
	if (myClassB != NULL)
	{
		delete myClassB;
		myClassB = NULL;
	}
}

int ClassA::nStart()
{
	printf_s("I'm nStart\n");
	
	myClassB->nCall(this, ch);
	return 0;
}

int ClassA::nCallBack(char *p)
{
	printf_s("I'm nCallBack\n");
	printf_s(ch);
	printf_s(p);
	return 0;
}


//ClassB.h文件 
#pragma once
#include 
#include 

class ClassA;


class ClassB
{
public:
	ClassB();
	~ClassB();

	int nCall(ClassA *myClassA, char *p);
	static unsigned int WINAPI sThread(LPVOID lpParam);
	
private:
	HANDLE hdl;
};


//ClassB.cpp文件
#include "stdafx.h"
#include "ClassB.h"
#include "ClassA.h"

ClassA *classA;
char ch[10];

ClassB::ClassB()
{
}

ClassB::~ClassB()
{
}

int ClassB::nCall(ClassA *myClassA, char *p)
{
	strcpy_s(ch, p);
	hdl = (HANDLE)_beginthreadex(NULL, 0, sThread, NULL, 0, NULL);

	WaitForSingleObject(hdl, INFINITE);//等待处理线程结束后调用回调函数返回通知;
	classA = (ClassA*)myClassA;
	printf_s("I'm nCall\n");
	classA->nCallBack(ch);
	//_endthreadex();

	return 0;
}

unsigned int ClassB::sThread(LPVOID lpParam)
{
	int i = 0;
	while (ch[i] != '\0')
	{
		ch[i] -=0x20;
		i++;
	}
	getchar();
	return 0;
}


//main.cpp
#include "stdafx.h"
#include "ClassA.h"


int _tmain(int argc, _TCHAR* argv[])
{
	ClassA myClassA;

	getchar();
	return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乘风-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值