一、前言
回调函数能够以高效的事件响应速度和灵活的模块解耦能力实现某项功能,而深受大家的钟爱。合理而又正确的使用将会为我们的程序增光加彩。废话不多说,下面就笔者经常遇到和使用的两种场景进行阐述,以此来给大家打来一些帮助和启发。
二、使用
1.参数中带有回调函数指针
#include <iostream>
using namespace std;
//external module or file
//this can be dependent with main module
#define PI 3.1415926
typedef float(*FUNPTR_AREA)(float, float);
float Triangle_Area(float width, float height, FUNPTR_AREA ptr)
{
return (1.0 / 2) * ptr(width, height);
}
float Circle_Area(float radius, FUNPTR_AREA ptr)
{
return (1.0 / 2) * ptr(2 * PI*radius, radius);
}
//main module or file
float Rectangle_Area(float width, float height)
{
return width * height;
}
int main()
{
cout<<"The rectangle with width is 3 and height is 4 whose area is:"<< Rectangle_Area(3, 4)<<endl;
cout << "The triangle with width is 3 and height is 4 whose area is:" << Triangle_Area(3, 4, Rectangle_Area) << endl;
cout << "The circle with radius is 3 whose area is:" << Circle_Area(3, Rectangle_Area) << endl;
return 0;
}
运行结果如下:
这种为临时调用、临时返回,使用的场景较为简单。
2.通过Register向主模块注册系列的实现处理方法
#include <vector>
class IFileOperation {
public:
virtual void OnFileOpen() = 0;
virtual void OnFileChange() = 0;
virtual void OnFileSave() = 0;
//etc...
};
typedef enum struct ModuleType_ {
FILE_OPERATUON,
MODULE_COUNT
//etc...
}ModuleType;
std::vector<void*> g_FileOperationMgr((size_t)ModuleType_::MODULE_COUNT);
void Register(ModuleType type,void* ptr)
{
int index = (int)type;
g_FileOperationMgr[index] = ptr;
}
void* GetHandler(ModuleType type)
{
int index = (int)type;
return g_FileOperationMgr[index];
}
//external module or file
//this can be dependent with main module
class MyFileOperation :public IFileOperation {
void OnFileOpen() override { cout << "File is Opening..."<<endl; }
void OnFileChange() override { cout << "File is Changing..."<<endl; }
void OnFileSave() override { cout << "File is Saving..."<<endl; }
};
MyFileOperation g_MyFileOperation;
int main()
{
Register(ModuleType_::FILE_OPERATUON, &g_MyFileOperation);
//Open happen
for (int i = 0; i < g_FileOperationMgr.size(); i++)
{
IFileOperation*pFileOperation = (IFileOperation *)g_FileOperationMgr[i];
pFileOperation->OnFileOpen();
}
//change happen
for (int i = 0; i < g_FileOperationMgr.size(); i++)
{
IFileOperation*pFileOperation = (IFileOperation *)g_FileOperationMgr[i];
pFileOperation->OnFileChange();
}
//Save happen
for (int i = 0; i < g_FileOperationMgr.size(); i++)
{
IFileOperation*pFileOperation = (IFileOperation *)g_FileOperationMgr[i];
pFileOperation->OnFileSave();
}
return 0;
}
运行结果如下:
这种在特定的情景下会触发事件的响应,主模块进行管理,而各个子模块负责继承注册实现。很适合一般的大型模块、动态库、插件模块,在一些跨平台库设计方面也用的比较多!