带有指向方法回调的指针的通用回调模板 class
Universal Callback template class with pointer to method callback
受此处另一篇关于 SO 的文章 (C++ callback using class member) 的启发,我尝试编写一个通用的 CallbackHandler。
CallbackHandler.hpp
#pragma once
#include <functional>
template <typename CallbackClass, typename CallbackArgType>
class CallbackHandler
{
public:
std::function<void(CallbackArgType ct)> m_callbackFunc;
CallbackHandler(CallbackClass * handler, std::function<void(CallbackArgType)> method)
{
//m_callbackFunc is supposed to stand for a member to pointer callback function with one
//parameter of any type
m_callbackFunc = std::bind(method, handler, std::placeholders::_1);
}
};
#include "wrapper_T.cpp"
我想在其他几个模板中使用它 namespaces/classes 就像这里:
wrapper.hpp
//this wrappers main purpose is to combine the constructor of a non templated class (MyModule)
//and hold a (global) callback method for it (m_parentCallback)
namespace wrapper
{
extern std::function<void(wxImage *)> m_parentCallback;
template<typename ParentClass>
MyModule GetNewModule(ParentClass* parent, void (ParentClass::* method)(wxImage *));
}
wrapper.cpp
namespace wrapper
{
//This is only to avoid multiple definition error - actual definition is in wrapper_T.cpp
std::function<void(wxImage *)> m_parentCallback;
}
wrapper_T.cpp
namespace wrapper
{
template<typename ParentClass>
MyModule GetNewModule(ParentClass* parent, void (ParentClass::* method)(wxImage *))
{
//the callback type of this wrapper/class is wxImage*
std::shared_ptr<CallbackHandler<ParentClass, wxImage*>> handler =
std::make_shared< CallbackHandler<ParentClass, wxImage*>>(parent, method);
//EDIT - SOLVED: <- Error C2664: Cant convert argument 2 from "void (__thiscall MyModule::*)(void)" to "std::function<void(wxImage*)>"
m_parentCallback = std::bind(&CallbackHandler<ParentClass, wxImage*>::m_callbackFunc, handler, std::placeholders::_1);
//<- Error C2679: no suitable binary operator "=" found
return std::make_unique<MyModule>();
}
}
我想像这样使用回调:
MyModule.cpp
wrapper::m_parentCallback(&img);
我想像这样初始化整个东西:
MainClass.cpp
MainClass::MainClass()
{
//declared in header: std::unique_ptr<MyModule> module
module = std::move(wrapper::GetNewModule(this, &MainClass::CallbackFunc));
}
void MainClass::CallbackFunc(wxImage * img)
{ /* do something with it */ }
我有 class 和 "this" 指针以及指向方法 "CallbackFunc" 的指针,应该没问题。
但是我看不到如何将我的 CallbackHandler class 用于 std::function 回调指针。
或者我是不是用包装器持有指向 CallbackHandler 的方法的指针,而后者持有指向实际回调方法的方法的指针?
所有这些都不是设计选择,我只希望 CallbackHandler 具有可移植性和工作性,同时具有易于使用的界面。
编辑:
我尝试在代码上应用评论建议,但我太快了
声称第一个问题已解决。该错误只是被下一个错误隐藏了。如果我尝试仅使用这一行进行编译:
std::shared_ptr<CallbackHandler<ParentClass, wxImage*>> handler =
std::make_shared< CallbackHandler<ParentClass, wxImage*>>(parent, method);
//<- Error C2664: "CallbackHandler<ParentClass,wxImage *>::
//CallbackHandler(CallbackHandler<ParentClass,wxImage *> &&)"
//: converting argument 2 from "void (__thiscall MainClass::* )(wxImage *)"
//to "std::function<void (wxImage *)>" not possible
// with
// [
// ParentClass=MainClass
]
//(freely translated into english by me)
因此,缺少参数并不是唯一的问题。
如果方法(成员函数)上的 std::bind 不起作用,我也必须更改 CallbackClass,不是吗?
也许沿着这些路线:
std::function<void(CallbackArgType cat)> m_callbackFunc;
CallbackHandler(CallbackClass * handler, std::function<void(CallbackArgType)> method)
{
//m_callbackFunc = std::bind(method, handler, std::placeholders::_1);
m_callbackFunc = [method](auto img) { method(img); };
}
替换
m_parentCallback = std::bind(&CallbackHandler<ParentClass, wxImage*>::m_callbackFunc, handler, std::placeholders::_1);
与
m_parentCallback = [handler](auto img){ handler->m_parentCallback(img); };
我不认为 bind
被设计为在一切之上使用成员函子对象。但是 lambda 可以无缝处理。
我注意到我的问题正在被每个事件处理程序调用事件函数解决。所以我使用事件处理程序作为我的 CallbackHandler 的基础。我发现并使用了这个事件处理程序,因为肯定还有许多其他好的书面示例:
https://www.codeproject.com/Articles/1256352/CppEvent-How-to-Implement-Events-using-Standard-Cp#holdingHandlerFunction
我只是将它包裹在 class 中,这对我的目的来说有点矫枉过正,但它确实有效。 Shmuel Zang 的所有学分(参见上面的 link)
EventHandler.hpp
#ifndef EventHandler_hpp
#define EventHandler_hpp
// https://www.codeproject.com/Articles/1256352/CppEvent-How-to-Implement-Events-using-Standard-Cp#holdingHandlerFunction
#include <functional>
#include <list>
#include <algorithm>
#include <utility>
#include <atomic>
#include <mutex>
#include <future>
namespace EventHandler
{
template <typename... Args> class EventHandler_Base
{
public:
typedef std::function<void(Args...)> handler_func_type;
typedef unsigned int handler_id_type;
explicit EventHandler_Base(const handler_func_type& handlerFunc)
: m_handlerFunc(handlerFunc)
{
m_handlerId = ++m_handlerIdCounter;
}
// copy constructor
EventHandler_Base(const EventHandler_Base& src)
: m_handlerFunc(src.m_handlerFunc), m_handlerId(src.m_handlerId)
{
}
// move constructor
EventHandler_Base(EventHandler_Base&& src)
: m_handlerFunc(std::move(src.m_handlerFunc)), m_handlerId(src.m_handlerId)
{
}
// copy assignment operator
EventHandler_Base& operator=(const EventHandler_Base& src)
{
m_handlerFunc = src.m_handlerFunc;
m_handlerId = src.m_handlerId;
return *this;
}
// move assignment operator
EventHandler_Base& operator=(EventHandler_Base&& src)
{
std::swap(m_handlerFunc, src.m_handlerFunc);
m_handlerId = src.m_handlerId;
return *this;
}
// function call operator
void operator()(Args... params) const
{
if (m_handlerFunc)
{
m_handlerFunc(params...);
}
}
bool operator==(const EventHandler_Base& other) const
{
return m_handlerId == other.m_handlerId;
}
operator bool() const
{
return m_handlerFunc;
}
handler_id_type id() const
{
return m_handlerId;
}
private:
handler_func_type m_handlerFunc;
handler_id_type m_handlerId;
static std::atomic_uint m_handlerIdCounter;
};
template <typename... Args> std::atomic_uint EventHandler_Base<Args...>::m_handlerIdCounter(0);
template <typename... Args> class Event_Base
{
public:
typedef EventHandler_Base<Args...> handler_type;
Event_Base()
{
}
// copy constructor
Event_Base(const Event_Base& src)
{
std::lock_guard<std::mutex> lock(src.m_handlersLocker);
m_handlers = src.m_handlers;
}
// move constructor
Event_Base(Event_Base&& src)
{
std::lock_guard<std::mutex> lock(src.m_handlersLocker);
m_handlers = std::move(src.m_handlers);
}
// copy assignment operator
Event_Base& operator=(const Event_Base& src)
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
std::lock_guard<std::mutex> lock2(src.m_handlersLocker);
m_handlers = src.m_handlers;
return *this;
}
// move assignment operator
Event_Base& operator=(Event_Base&& src)
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
std::lock_guard<std::mutex> lock2(src.m_handlersLocker);
std::swap(m_handlers, src.m_handlers);
return *this;
}
typename handler_type::handler_id_type add(const handler_type& handler)
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
m_handlers.push_back(handler);
return handler.id();
}
inline typename handler_type::handler_id_type add(const typename handler_type::handler_func_type& handler)
{
return add(handler_type(handler));
}
bool remove(const handler_type& handler)
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
auto it = std::find(m_handlers.begin(), m_handlers.end(), handler);
if (it != m_handlers.end())
{
m_handlers.erase(it);
return true;
}
return false;
}
bool remove_id(const typename handler_type::handler_id_type& handlerId)
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
auto it = std::find_if(m_handlers.begin(), m_handlers.end(),
[handlerId](const handler_type& handler) { return handler.id() == handlerId; });
if (it != m_handlers.end())
{
m_handlers.erase(it);
return true;
}
return false;
}
void call(Args... params) const
{
handler_collection_type handlersCopy = get_handlers_copy();
call_impl(handlersCopy, params...);
}
std::future<void> call_async(Args... params) const
{
return std::async(std::launch::async, [this](Args... asyncParams) { call(asyncParams...); }, params...);
}
inline void operator()(Args... params) const
{
call(params...);
}
inline typename handler_type::handler_id_type operator+=(const handler_type& handler)
{
return add(handler);
}
inline typename handler_type::handler_id_type operator+=(const typename handler_type::handler_func_type& handler)
{
return add(handler);
}
inline bool operator-=(const handler_type& handler)
{
return remove(handler);
}
protected:
typedef std::list<handler_type> handler_collection_type;
void call_impl(const handler_collection_type& handlers, Args... params) const
{
for (const auto& handler : handlers)
{
handler(params...);
}
}
handler_collection_type get_handlers_copy() const
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
// Since the function return value is by copy,
// before the function returns (and destruct the lock_guard object),
// it creates a copy of the m_handlers container.
return m_handlers;
}
private:
handler_collection_type m_handlers;
mutable std::mutex m_handlersLocker;
};
}
#endif // EventHandler_hpp
然后我使用这个泛型 class 来保存回调成员方法:
CallbackHandler.hpp
#ifndef CallbackHandler_hpp
#define CallbackHandler_hpp
#pragma once
#include "EventHandler.hpp"
#include <functional>
#include <mutex>
using namespace EventHandler;
template <typename... Args>
class CallbackHandler
{
public:
typedef std::function<void(Args...)> callbackFunc_type;
explicit CallbackHandler() : mb_callbackIsSet(false), mi_handlerID(0){}
explicit CallbackHandler(const callbackFunc_type& handlerFunc) : mb_callbackIsSet(false), mi_handlerID(0)
{
SetCallbackMethod(handlerFunc);
}
~CallbackHandler()
{
m_callbackEvent.remove_id(mi_handlerID);
}
void SetCallbackMethod(const callbackFunc_type& handlerFunc)
{
m_callbackEvent.remove_id(mi_handlerID);
mi_handlerID = m_callbackEvent.add([=](Args... params) {
handlerFunc(params...);
});
mb_callbackIsSet = true;
}
bool DoCallback(Args... params)
{
if (mb_callbackIsSet)
{
std::lock_guard<std::mutex> lock(callbackLocker);
m_callbackEvent(params...);
return true;
}
return false;
}
private:
unsigned int mi_handlerID;
Event_Base<Args...> m_callbackEvent;
bool mb_callbackIsSet;
std::mutex callbackLocker;
};
#endif //CallbackHandler_hpp
我现在可以在每个 class 中使用 CallbackHandler:
//Imagine an example class named Screenshotmodul
//In this example I use wxImage as a callback object, it is the output of my Screenshotmodul class and should be given back to my main class
//It could be any other (or several others like this: <ObjectType, OtherCallbackType> )
class Screenshotmodul
{
public:
//[...]
CallbackHandler<wxImage> m_callbackHandler;
template<typename ParentClass>
void SetCallbackMethod(ParentClass* parent, void (ParentClass::* method)(wxImage))
{
//using the given object pointer and the given member method in a lambda function
//saving that lambda as callback method
m_callbackHandler.SetCallbackMethod([=](wxImage img) {
(parent->*method)(img); });
}
}
在我的主程序中 class 然后我可以设置一个回调方法:
std::unique_ptr<Screenshotmodul> sm = std::make_unique<Screenshotmodul>();
sm->SetCallbackMethod(this, &MyMainClass::CallbackfuncForScreenshotmodul);
//Of course there should be a callback function as just described:
void MyMainClass::CallbackfuncForScreenshotmodul(wxImage img)
{
//img now contains the callback value, that the Screenshotmodul class created
}
这是我的方法,并不完美,但对我有用。
干杯
纳图
受此处另一篇关于 SO 的文章 (C++ callback using class member) 的启发,我尝试编写一个通用的 CallbackHandler。
CallbackHandler.hpp
#pragma once
#include <functional>
template <typename CallbackClass, typename CallbackArgType>
class CallbackHandler
{
public:
std::function<void(CallbackArgType ct)> m_callbackFunc;
CallbackHandler(CallbackClass * handler, std::function<void(CallbackArgType)> method)
{
//m_callbackFunc is supposed to stand for a member to pointer callback function with one
//parameter of any type
m_callbackFunc = std::bind(method, handler, std::placeholders::_1);
}
};
#include "wrapper_T.cpp"
我想在其他几个模板中使用它 namespaces/classes 就像这里:
wrapper.hpp
//this wrappers main purpose is to combine the constructor of a non templated class (MyModule)
//and hold a (global) callback method for it (m_parentCallback)
namespace wrapper
{
extern std::function<void(wxImage *)> m_parentCallback;
template<typename ParentClass>
MyModule GetNewModule(ParentClass* parent, void (ParentClass::* method)(wxImage *));
}
wrapper.cpp
namespace wrapper
{
//This is only to avoid multiple definition error - actual definition is in wrapper_T.cpp
std::function<void(wxImage *)> m_parentCallback;
}
wrapper_T.cpp
namespace wrapper
{
template<typename ParentClass>
MyModule GetNewModule(ParentClass* parent, void (ParentClass::* method)(wxImage *))
{
//the callback type of this wrapper/class is wxImage*
std::shared_ptr<CallbackHandler<ParentClass, wxImage*>> handler =
std::make_shared< CallbackHandler<ParentClass, wxImage*>>(parent, method);
//EDIT - SOLVED: <- Error C2664: Cant convert argument 2 from "void (__thiscall MyModule::*)(void)" to "std::function<void(wxImage*)>"
m_parentCallback = std::bind(&CallbackHandler<ParentClass, wxImage*>::m_callbackFunc, handler, std::placeholders::_1);
//<- Error C2679: no suitable binary operator "=" found
return std::make_unique<MyModule>();
}
}
我想像这样使用回调:
MyModule.cpp
wrapper::m_parentCallback(&img);
我想像这样初始化整个东西:
MainClass.cpp
MainClass::MainClass()
{
//declared in header: std::unique_ptr<MyModule> module
module = std::move(wrapper::GetNewModule(this, &MainClass::CallbackFunc));
}
void MainClass::CallbackFunc(wxImage * img)
{ /* do something with it */ }
我有 class 和 "this" 指针以及指向方法 "CallbackFunc" 的指针,应该没问题。 但是我看不到如何将我的 CallbackHandler class 用于 std::function 回调指针。
或者我是不是用包装器持有指向 CallbackHandler 的方法的指针,而后者持有指向实际回调方法的方法的指针?
所有这些都不是设计选择,我只希望 CallbackHandler 具有可移植性和工作性,同时具有易于使用的界面。
编辑: 我尝试在代码上应用评论建议,但我太快了 声称第一个问题已解决。该错误只是被下一个错误隐藏了。如果我尝试仅使用这一行进行编译:
std::shared_ptr<CallbackHandler<ParentClass, wxImage*>> handler =
std::make_shared< CallbackHandler<ParentClass, wxImage*>>(parent, method);
//<- Error C2664: "CallbackHandler<ParentClass,wxImage *>::
//CallbackHandler(CallbackHandler<ParentClass,wxImage *> &&)"
//: converting argument 2 from "void (__thiscall MainClass::* )(wxImage *)"
//to "std::function<void (wxImage *)>" not possible
// with
// [
// ParentClass=MainClass
]
//(freely translated into english by me)
因此,缺少参数并不是唯一的问题。 如果方法(成员函数)上的 std::bind 不起作用,我也必须更改 CallbackClass,不是吗? 也许沿着这些路线:
std::function<void(CallbackArgType cat)> m_callbackFunc;
CallbackHandler(CallbackClass * handler, std::function<void(CallbackArgType)> method)
{
//m_callbackFunc = std::bind(method, handler, std::placeholders::_1);
m_callbackFunc = [method](auto img) { method(img); };
}
替换
m_parentCallback = std::bind(&CallbackHandler<ParentClass, wxImage*>::m_callbackFunc, handler, std::placeholders::_1);
与
m_parentCallback = [handler](auto img){ handler->m_parentCallback(img); };
我不认为 bind
被设计为在一切之上使用成员函子对象。但是 lambda 可以无缝处理。
我注意到我的问题正在被每个事件处理程序调用事件函数解决。所以我使用事件处理程序作为我的 CallbackHandler 的基础。我发现并使用了这个事件处理程序,因为肯定还有许多其他好的书面示例: https://www.codeproject.com/Articles/1256352/CppEvent-How-to-Implement-Events-using-Standard-Cp#holdingHandlerFunction
我只是将它包裹在 class 中,这对我的目的来说有点矫枉过正,但它确实有效。 Shmuel Zang 的所有学分(参见上面的 link)
EventHandler.hpp
#ifndef EventHandler_hpp
#define EventHandler_hpp
// https://www.codeproject.com/Articles/1256352/CppEvent-How-to-Implement-Events-using-Standard-Cp#holdingHandlerFunction
#include <functional>
#include <list>
#include <algorithm>
#include <utility>
#include <atomic>
#include <mutex>
#include <future>
namespace EventHandler
{
template <typename... Args> class EventHandler_Base
{
public:
typedef std::function<void(Args...)> handler_func_type;
typedef unsigned int handler_id_type;
explicit EventHandler_Base(const handler_func_type& handlerFunc)
: m_handlerFunc(handlerFunc)
{
m_handlerId = ++m_handlerIdCounter;
}
// copy constructor
EventHandler_Base(const EventHandler_Base& src)
: m_handlerFunc(src.m_handlerFunc), m_handlerId(src.m_handlerId)
{
}
// move constructor
EventHandler_Base(EventHandler_Base&& src)
: m_handlerFunc(std::move(src.m_handlerFunc)), m_handlerId(src.m_handlerId)
{
}
// copy assignment operator
EventHandler_Base& operator=(const EventHandler_Base& src)
{
m_handlerFunc = src.m_handlerFunc;
m_handlerId = src.m_handlerId;
return *this;
}
// move assignment operator
EventHandler_Base& operator=(EventHandler_Base&& src)
{
std::swap(m_handlerFunc, src.m_handlerFunc);
m_handlerId = src.m_handlerId;
return *this;
}
// function call operator
void operator()(Args... params) const
{
if (m_handlerFunc)
{
m_handlerFunc(params...);
}
}
bool operator==(const EventHandler_Base& other) const
{
return m_handlerId == other.m_handlerId;
}
operator bool() const
{
return m_handlerFunc;
}
handler_id_type id() const
{
return m_handlerId;
}
private:
handler_func_type m_handlerFunc;
handler_id_type m_handlerId;
static std::atomic_uint m_handlerIdCounter;
};
template <typename... Args> std::atomic_uint EventHandler_Base<Args...>::m_handlerIdCounter(0);
template <typename... Args> class Event_Base
{
public:
typedef EventHandler_Base<Args...> handler_type;
Event_Base()
{
}
// copy constructor
Event_Base(const Event_Base& src)
{
std::lock_guard<std::mutex> lock(src.m_handlersLocker);
m_handlers = src.m_handlers;
}
// move constructor
Event_Base(Event_Base&& src)
{
std::lock_guard<std::mutex> lock(src.m_handlersLocker);
m_handlers = std::move(src.m_handlers);
}
// copy assignment operator
Event_Base& operator=(const Event_Base& src)
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
std::lock_guard<std::mutex> lock2(src.m_handlersLocker);
m_handlers = src.m_handlers;
return *this;
}
// move assignment operator
Event_Base& operator=(Event_Base&& src)
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
std::lock_guard<std::mutex> lock2(src.m_handlersLocker);
std::swap(m_handlers, src.m_handlers);
return *this;
}
typename handler_type::handler_id_type add(const handler_type& handler)
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
m_handlers.push_back(handler);
return handler.id();
}
inline typename handler_type::handler_id_type add(const typename handler_type::handler_func_type& handler)
{
return add(handler_type(handler));
}
bool remove(const handler_type& handler)
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
auto it = std::find(m_handlers.begin(), m_handlers.end(), handler);
if (it != m_handlers.end())
{
m_handlers.erase(it);
return true;
}
return false;
}
bool remove_id(const typename handler_type::handler_id_type& handlerId)
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
auto it = std::find_if(m_handlers.begin(), m_handlers.end(),
[handlerId](const handler_type& handler) { return handler.id() == handlerId; });
if (it != m_handlers.end())
{
m_handlers.erase(it);
return true;
}
return false;
}
void call(Args... params) const
{
handler_collection_type handlersCopy = get_handlers_copy();
call_impl(handlersCopy, params...);
}
std::future<void> call_async(Args... params) const
{
return std::async(std::launch::async, [this](Args... asyncParams) { call(asyncParams...); }, params...);
}
inline void operator()(Args... params) const
{
call(params...);
}
inline typename handler_type::handler_id_type operator+=(const handler_type& handler)
{
return add(handler);
}
inline typename handler_type::handler_id_type operator+=(const typename handler_type::handler_func_type& handler)
{
return add(handler);
}
inline bool operator-=(const handler_type& handler)
{
return remove(handler);
}
protected:
typedef std::list<handler_type> handler_collection_type;
void call_impl(const handler_collection_type& handlers, Args... params) const
{
for (const auto& handler : handlers)
{
handler(params...);
}
}
handler_collection_type get_handlers_copy() const
{
std::lock_guard<std::mutex> lock(m_handlersLocker);
// Since the function return value is by copy,
// before the function returns (and destruct the lock_guard object),
// it creates a copy of the m_handlers container.
return m_handlers;
}
private:
handler_collection_type m_handlers;
mutable std::mutex m_handlersLocker;
};
}
#endif // EventHandler_hpp
然后我使用这个泛型 class 来保存回调成员方法:
CallbackHandler.hpp
#ifndef CallbackHandler_hpp
#define CallbackHandler_hpp
#pragma once
#include "EventHandler.hpp"
#include <functional>
#include <mutex>
using namespace EventHandler;
template <typename... Args>
class CallbackHandler
{
public:
typedef std::function<void(Args...)> callbackFunc_type;
explicit CallbackHandler() : mb_callbackIsSet(false), mi_handlerID(0){}
explicit CallbackHandler(const callbackFunc_type& handlerFunc) : mb_callbackIsSet(false), mi_handlerID(0)
{
SetCallbackMethod(handlerFunc);
}
~CallbackHandler()
{
m_callbackEvent.remove_id(mi_handlerID);
}
void SetCallbackMethod(const callbackFunc_type& handlerFunc)
{
m_callbackEvent.remove_id(mi_handlerID);
mi_handlerID = m_callbackEvent.add([=](Args... params) {
handlerFunc(params...);
});
mb_callbackIsSet = true;
}
bool DoCallback(Args... params)
{
if (mb_callbackIsSet)
{
std::lock_guard<std::mutex> lock(callbackLocker);
m_callbackEvent(params...);
return true;
}
return false;
}
private:
unsigned int mi_handlerID;
Event_Base<Args...> m_callbackEvent;
bool mb_callbackIsSet;
std::mutex callbackLocker;
};
#endif //CallbackHandler_hpp
我现在可以在每个 class 中使用 CallbackHandler:
//Imagine an example class named Screenshotmodul
//In this example I use wxImage as a callback object, it is the output of my Screenshotmodul class and should be given back to my main class
//It could be any other (or several others like this: <ObjectType, OtherCallbackType> )
class Screenshotmodul
{
public:
//[...]
CallbackHandler<wxImage> m_callbackHandler;
template<typename ParentClass>
void SetCallbackMethod(ParentClass* parent, void (ParentClass::* method)(wxImage))
{
//using the given object pointer and the given member method in a lambda function
//saving that lambda as callback method
m_callbackHandler.SetCallbackMethod([=](wxImage img) {
(parent->*method)(img); });
}
}
在我的主程序中 class 然后我可以设置一个回调方法:
std::unique_ptr<Screenshotmodul> sm = std::make_unique<Screenshotmodul>();
sm->SetCallbackMethod(this, &MyMainClass::CallbackfuncForScreenshotmodul);
//Of course there should be a callback function as just described:
void MyMainClass::CallbackfuncForScreenshotmodul(wxImage img)
{
//img now contains the callback value, that the Screenshotmodul class created
}
这是我的方法,并不完美,但对我有用。
干杯 纳图