回调函数的简单说明(注释中已经详细说明)

本文详细介绍了回调函数的基本写法,包括独立的回调函数和在类中的实现。此外,还探讨了如何在调用者一方利用回调函数进行操作,如实现进度值的回调,以增强代码的交互性。

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

第一部分    基本的回调函数写

// callback.cpp : 定义控制台应用程序的入口点。
// 回调函数就是一个通过函数指针调用的函数
//

#include "stdafx.h"
#include <iostream>

void OutputSchedule1(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
{
	std::cout<<"schedule1 = "<< schedule <<std::endl;
	std::cout<<"str1 = "<< str <<std::endl;
}

void OutputSchedule2(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
{
	std::cout<<"schedule2 = "<< schedule <<std::endl;
	std::cout<<"str2 = "<< str <<std::endl;
}

// 以上部分可以包含在dll中,只要指定了callback的函数签名即可(本例:满足 void xxx(int, char*) 的函数)
//
// 以下的部分可以是调用dll部分的代码

typedef void (*mCallback)(int schedule, char* str); // 定义一个指向函数的函数指针

void caller(mCallback p) // 在main中调用的形式(mian直接调用);p是一个指针
{						// 调用之时,只要满足 void xxx(int, char*) 的函数都可以用做参数传入
						// 具体的操作有最终传到p的函数决定
	(*p)(1, "xxvvc456cs89cs-cs");
}

int _tmain(int argc, _TCHAR* argv[])
{
	caller(&OutputSchedule1);
	caller(&OutputSchedule2);
	return 0;
}



第二部分    类中的回调函数写法

// callback.cpp : 定义控制台应用程序的入口点。
// 类成员的回调函数实现,需要借助类对象
// 写法一

#include "stdafx.h"
#include <iostream>

class mClass
{
public:
	// 类中包含的是两个函数的实现过程
	void OutputSchedule1(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
	{
		std::cout<<"schedule1 = "<< schedule <<std::endl;
		std::cout<<"str1 = "<< str <<std::endl;
	}

	void OutputSchedule2(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
	{
		std::cout<<"schedule2 = "<< schedule <<std::endl;
		std::cout<<"str2 = "<< str <<std::endl;
	}

};

// 以上部分可以包含在dll中,只要指定了callback的函数签名即可(本例:满足 void xxx(int, char*) 的函数)
//
// 以下的部分可以是调用dll部分的代码

typedef void (mClass::*pMenberFunction)(int schedule, char* str); // 声明的符合‘类成员类型’的函数指针
void caller(mClass* pObj ,pMenberFunction p) // 在main中调用的形式(mian直接调用);p是一个指针;pObj最终用于传递类对象
{						// 调用之时,只要满足 void xxx(int, char*) 的函数都可以用做参数传入
						// 具体的操作有最终传到p的函数决定
	(pObj->*p)(1, "xxvvc456cs89cs-cs");
}

int _tmain(int argc, _TCHAR* argv[])
{
	mClass mItem;
	caller(&mItem, &mClass::OutputSchedule1); // 第二个参数p接受的变量是函数指针,注意是使用类中定义的函数名(类似泛称),而非(确定的某一个)mItem的成员
	caller(&mItem, &mClass::OutputSchedule2);
	return 0;
}




// callback.cpp : 定义控制台应用程序的入口点。
// 类成员的回调函数实现,需要借助类对象
// 写法二  使用模板

#include "stdafx.h"
#include <iostream>

class mClass
{
public:
	// 类中包含的是两个函数的实现过程
	void OutputSchedule1(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
	{
		std::cout<<"schedule1 = "<< schedule <<std::endl;
		std::cout<<"str1 = "<< str <<std::endl;
	}

	void OutputSchedule2(int schedule, char* str) // 要被调用的函数最终形式(main间接调用)
	{
		std::cout<<"schedule2 = "<< schedule <<std::endl;
		std::cout<<"str2 = "<< str <<std::endl;
	}
};

// 以上部分可以包含在dll中,只要指定了callback的函数签名即可(本例:满足 void xxx(int, char*) 的函数)
//
// 以下的部分可以是调用dll部分的代码

template<typename T> // !!仅修改此处及下下行,使用template:T 来替换类名:mClass
// 这样,就不局限为某一个类。只要类成员的形式满足 void xxx(int, char*) 就可以使用这个callback函数:caller
void caller(T* pObj, void(T::*p)(int schedule, char* str))// 在main中调用的形式(mian直接调用);p是一个指针;pObj最终用于传递类对象
{								// 调用之时,只要满足 void xxx(int, char*) 的函数都可以用做参数传入
								// 具体的操作有最终传到p的函数决定
	(pObj->*p)(1, "xxvvc456cs89cs-cs");
}

int _tmain(int argc, _TCHAR* argv[])
{
	mClass mItem;
	caller(&mItem, &mClass::OutputSchedule1); // 第二个参数p接受的变量是函数指针,注意是使用类中定义的函数名(类似泛称),而非(确定的某一个)mItem的成员
	caller(&mItem, &mClass::OutputSchedule2);
	return 0;
}



第三部分   类中调用回调函数,在调用者一方编写操作内容(比如可用于进度值回调)

// callback.cpp : 定义控制台应用程序的入口点。
// 类成员的回调函数实现,需要借助类对象
// 在类(或dll)中传值到main
// 比如:可以用于进度回调
//

#include "stdafx.h"
#include <iostream>

class mClass
{
public:

	typedef void(*mScheduleCallback)(int schedule, char* str);
	void caller(mScheduleCallback p) // 在类(dll)中传递两个参数(int schedule, char* str 亦即 1, "xxvvc456cs89cs-cs")给调用者
	{						// 传递出去的了两个参数的用途由调用者编写的函数决定
		p(1, "xxvvc456cs89cs-cs"); // 比如可以作为进度值回调给调用者
	}

};

// 以上部分可以包含在dll中,只要指定了callback的函数签名即可(本例:满足 void xxx(int, char*) 的函数)
//
// 以下的部分可以是调用dll部分的代码


void OutputSchedule1(int schedule, char* str) // 有调用者编写的函数指针指向的本体,也就是此处的两个参数的显示操作(main间接调用)
{
	std::cout<<"schedule1 = "<< schedule <<std::endl;
	std::cout<<"str1 = "<< str <<std::endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
	mClass mItem;
	mItem.caller(&OutputSchedule1); // 有无引用符号好像都可以,这个测试代码还看不出差异
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值