【发布时间】:2017-09-18 17:44:28
【问题描述】:
提前感谢您的支持。
我正在使用 C++11,我想存储一些类的公共成员函数以供以后用作回调函数;例如我想存储一些与此模板匹配的函数:void(classname::*)(void)。据我所知,我也必须存储他们的对象,这很好。例如:
// PSEUDO CODE
class A {
public:
void myfunc() {}
}myobj;
class B {
public:
void myfunc2() {}
}myobj2;
/* storing */
mystorageclass storage;
storage.push(&myobj, &A::myfunc);
storage.push(&myobj2, &B::myfunc2);
/* call them back */
(storage[0].object->*(storage[0].callback))();
(storage[1].object->*(storage[1].callback))();
有没有安全通用的方法来做到这一点?实际上我已经找到了一种方法,但我不确定它在处理器或编译器之间的可移植性。
//test.cpp - compiled with: g++ test.cpp -o test -std=c++11
#include <iostream>
#include <vector>
class A {
public:
void myfunc() { std::cout << "Test A::myfunc()" << std::endl; }
}myobj;
class B {
public:
void myfunc2() { std::cout << "Test B::myfunc2()" << std::endl; }
}myobj2;
struct Callback {
void* object;
void(* method)(void*);
};
std::vector<Callback> callbackList;
template<typename FunctionPtr>
void add(void* object, FunctionPtr fptr) {
Callback cb;
cb.object = object;
cb.method = (void(*)(void*))(*(void**)(&fptr));
callbackList.push_back(cb);
}
int main() {
//add to list for later use
add(&myobj, &A::myfunc);
add(&myobj2, &B::myfunc2);
//call them back
callbackList[0].method(callbackList[0].object);
callbackList[1].method(callbackList[1].object);
}
还有另一种方法;我觉得这样更安全:
//test2.cpp - compiled with: g++ test2.cpp -o test2 -std=c++11
#include <iostream>
#include <vector>
class A {
public:
void myfunc() { std::cout << "Test A::myfunc()" << std::endl; }
}myobj;
class B {
public:
void myfunc2() { std::cout << "Test B::myfunc2()" << std::endl; }
}myobj2;
struct Callback {
struct A;
A* object;
void(A::* method)();
void call() {
(object->*method)();
}
};
std::vector<Callback> callbackList;
template<typename FunctionPtr>
void add(void* object, FunctionPtr fptr) {
Callback cb;
cb.object = (Callback::A*)object;
cb.method = (void(Callback::A::*)())(fptr);
callbackList.push_back(cb);
}
int main() {
//add to list for later use
add(&myobj, &A::myfunc);
add(&myobj2, &B::myfunc2);
//call them back
callbackList[0].call();
callbackList[1].call();
}
这些用法安全吗?或者你有什么建议来代替这些。 谢谢。
【问题讨论】:
-
你试过编译第二个版本吗?它不应该编译。您不能使用
void*调用成员函数。 -
我试过了,但这些是我得到的最好的结果。 @CaptainObvlious
-
按照我给你的链接中的例子。首先使用
std::function来处理一些小而琐碎的事情,以便习惯它。一旦你熟悉了它,试着将它应用到你的代码中。 -
您想将函数存储在文件中还是让操作系统稍后加载它们?