调用从另一个 class 传递的回调
Calling a callback passed from another class
我想在另一个 (X) 中注册一个 class (Y) 的回调处理程序(方法)。由于可能的堆分配,我无法使用 std::function,并且我必须有权访问注册处理程序的 class 的成员。我也想避免静态函数。
我想出了一些办法,但一直坚持调用回调:
template<class T>
using clbkType = void(T::*)(void);
template<class T>
class X
{
public:
void registerClbck(clbkType<T> clbk) {
callback = clbk;
}
void call() {
callback(); // ERROR C2064: term does not evaluate to a function taking 0 arguments.
//(((X<T>*)this)->X<T>::callback)(); // same error
}
private:
clbkType<T> callback;
};
class Y
{
public:
Y() {
x.registerClbck(&Y::handler);
}
// just for a test: fire a callback in class X
void fire() {
x.call();
}
int getA() { return a; }
private:
int a{ 0 };
X<Y> x{};
void handler() {
a = 5;
}
};
int main()
{
Y y;
y.fire();
return y.getA();
}
link 编码:https://godbolt.org/z/PhY41xsWE
PS。我不确定这是否是一个安全的解决方案,所以请对此发表任何评论。
谢谢!
成员函数指针需要一个特定的class对象来调用,所以你需要这样做:
template<class T>
class X
{
public:
// ...
void call(T& obj) {
(obj.*callback)();
}
// ...
};
class Y
{
public:
// just for a test: fire a callback in class X
void fire() {
x.call(*this);
}
// ...
};
成员函数指针需要实例调用
如果你想绑定实例,这里有一个可能的实现方式。
template<typename T>
struct member_callback {
T* instance;
void(T::*callback)();
void operator()(){(instance->*callback)();}
};
template<typename T>
struct X{
void registerClbck(member_callback<T> clbk) { callback = clbk; }
void call() { callback(); }
member_callback<T> callback;
};
struct Y{
public:
Y() { x.registerClbck({this,&Y::handler}); }
void fire() { x.call(); }
int getA() { return a; }
private:
int a{ 0 };
X<Y> x{};
void handler(){ a = 5; }
};
int main()
{
Y y;
y.fire();
return y.getA();
}
我想在另一个 (X) 中注册一个 class (Y) 的回调处理程序(方法)。由于可能的堆分配,我无法使用 std::function,并且我必须有权访问注册处理程序的 class 的成员。我也想避免静态函数。 我想出了一些办法,但一直坚持调用回调:
template<class T>
using clbkType = void(T::*)(void);
template<class T>
class X
{
public:
void registerClbck(clbkType<T> clbk) {
callback = clbk;
}
void call() {
callback(); // ERROR C2064: term does not evaluate to a function taking 0 arguments.
//(((X<T>*)this)->X<T>::callback)(); // same error
}
private:
clbkType<T> callback;
};
class Y
{
public:
Y() {
x.registerClbck(&Y::handler);
}
// just for a test: fire a callback in class X
void fire() {
x.call();
}
int getA() { return a; }
private:
int a{ 0 };
X<Y> x{};
void handler() {
a = 5;
}
};
int main()
{
Y y;
y.fire();
return y.getA();
}
link 编码:https://godbolt.org/z/PhY41xsWE
PS。我不确定这是否是一个安全的解决方案,所以请对此发表任何评论。
谢谢!
成员函数指针需要一个特定的class对象来调用,所以你需要这样做:
template<class T>
class X
{
public:
// ...
void call(T& obj) {
(obj.*callback)();
}
// ...
};
class Y
{
public:
// just for a test: fire a callback in class X
void fire() {
x.call(*this);
}
// ...
};
成员函数指针需要实例调用
如果你想绑定实例,这里有一个可能的实现方式。
template<typename T>
struct member_callback {
T* instance;
void(T::*callback)();
void operator()(){(instance->*callback)();}
};
template<typename T>
struct X{
void registerClbck(member_callback<T> clbk) { callback = clbk; }
void call() { callback(); }
member_callback<T> callback;
};
struct Y{
public:
Y() { x.registerClbck({this,&Y::handler}); }
void fire() { x.call(); }
int getA() { return a; }
private:
int a{ 0 };
X<Y> x{};
void handler(){ a = 5; }
};
int main()
{
Y y;
y.fire();
return y.getA();
}