gpt4 book ai didi

c++ - 如何改进c风格的函数回调系统?

转载 作者:行者123 更新时间:2023-11-30 04:31:45 25 4
gpt4 key购买 nike

我有一个我无法更改的类 (SuperClass),它有一个我不太喜欢的用于添加回调的接口(interface),但我无法改进它。是否可以通过使用一些模板魔法来摆脱所有包装函数?

#include <iostream>
#include <string>
#include <vector>

enum EventType
{
OkButtonPressed = 0,
CancelButtonPressed,
KeyPad1ButtonPressed,
KeyPad2ButtonPressed,
KeyPad3ButtonPressed,
KeyPad4ButtonPressed,
KeyPad5ButtonPressed,
SomeOtherNonButtonEvent,
EventType_count
};


// Not sure how the SuperClass is implemented, but from the outside all you can see is
// the AddCallback(). The class can not be changed. Same applies to the callback typedef

typedef void (*EventCallback)(int argument, void *callbackOwner);
class SuperClass
{
private:
#define CallbackPair std::pair<EventCallback, void*>
std::vector<CallbackPair> m_callbackList[EventType_count];

public:
void AddCallback(EventType eventType, EventCallback function, void * callbackOwner)
{
CallbackPair pair(function, callbackOwner);
m_callbackList[eventType].push_back(pair);
}

void TriggerEvent(EventType type)
{
int someArguemt = (int)type;
for(unsigned int i = 0; i < m_callbackList[type].size(); i++)
m_callbackList[type][i].first(someArguemt, m_callbackList[type][i].second);
}
};

class MyClass
{
public:
void OnKeypadFunction(int argument){std::cout << "OnKeypadFunction called with " << argument << std::endl;}
void OnOkFunction(int argument){std::cout << "OnOkFunction called with " << argument << std::endl;}
void OnCancelFunction(int argument){std::cout << "OnCancelFunction called with " << argument << std::endl;}
};

// Wrapper functions which i would like to remove
static void s_OnKeypadFunctionWrapper(int arguemt, void *callbackOwner)
{
((MyClass*)callbackOwner)->OnKeypadFunction(arguemt);
}

static void s_OnOkFunctionWrapper(int arguemt, void *callbackOwner)
{
((MyClass*)callbackOwner)->OnOkFunction(arguemt);
}

static void s_OnCancelFunctionWrapper(int arguemt, void *callbackOwner)
{
((MyClass*)callbackOwner)->OnCancelFunction(arguemt);
}


int main()
{
SuperClass super;
MyClass myClass;

// Register some callbacks
super.AddCallback(KeyPad1ButtonPressed, s_OnKeypadFunctionWrapper, &myClass);
super.AddCallback(KeyPad2ButtonPressed, s_OnKeypadFunctionWrapper, &myClass);
super.AddCallback(KeyPad3ButtonPressed, s_OnKeypadFunctionWrapper, &myClass);
super.AddCallback(KeyPad4ButtonPressed, s_OnKeypadFunctionWrapper, &myClass);
super.AddCallback(KeyPad5ButtonPressed, s_OnKeypadFunctionWrapper, &myClass);
super.AddCallback(OkButtonPressed, s_OnOkFunctionWrapper, &myClass);

// How I would like to add the code..
/*
super.AddCallback(KeyPad1ButtonPressed, myClass->OnKeypadFunction, NULL);
super.AddCallback(KeyPad2ButtonPressed, myClass->OnKeypadFunction, NULL);
super.AddCallback(KeyPad3ButtonPressed, myClass->OnKeypadFunction, NULL);
super.AddCallback(KeyPad4ButtonPressed, myClass->OnKeypadFunction, NULL);
super.AddCallback(KeyPad5ButtonPressed, myClass->OnKeypadFunction, NULL);
super.AddCallback(OkButtonPressed, myClass->s_OnOkFunctionWrapper, NULL);
*/


// This is called some other place...
super.TriggerEvent(OkButtonPressed);
super.TriggerEvent(KeyPad1ButtonPressed);
super.TriggerEvent(KeyPad5ButtonPressed);
}

最佳答案

这样的事情怎么样:

template <typename T, void (T::*MemberFunction)(int)>
struct CallbackHelper
{
static void EventHandler(int argument, void *callbackOwner)
{
auto myClass = static_cast<T*>(callbackOwner);
((myClass)->*(MemberFunction))(argument);
}
};

这会让你像这样注册你的处理程序:

super.AddCallback(OkButtonPressed, CallbackHelper<MyClass, &MyClass::OnOkFunction>::EventHandler, &myClass);

关于c++ - 如何改进c风格的函数回调系统?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8071305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com