这个列表必须包含函数,它们可能来自不同的命名空间甚至是实例类的方法 然后将迭代此列表并调用所有函数和方法。如果他们也可以包含参数那就太好了。
我正在考虑使用std :: vector,但我怀疑这个猜测远非正确。
你推荐我什么方法?欢迎大家帮忙。
答案 0 :(得分:4)
如果你的编译器已经支持它,你可以使用std :: function和std :: bind。
#include <functional>
#include <vector>
void x(int) {}
void y() {}
class Z {
public:
void z() {}
};
int main(int argc, char *argv[])
{
typedef std::function<void ()> VoidFunc;
typedef std::vector<VoidFunc> FuncVector;
FuncVector functions;
functions.push_back(std::bind(&x, 1));
functions.push_back(&y);
Z z1;
functions.push_back(std::bind(&Z::z, z1));
for(FuncVector::iterator i = functions.begin(); i != functions.end(); i++) {
(*i)();
}
return 0;
}
答案 1 :(得分:2)
如果您不想使用现有的解决方案,例如boost :: function,则需要创建一个表示函数的基类,然后创建包含各种函数源的派生类。例如:
#include <iostream>
#include <list>
using std::cout;
using std::list;
struct Function {
virtual ~Function() { }
virtual void operator()() = 0;
};
struct PlainFunction : Function {
PlainFunction(void (*function_ptr_arg)()) : function_ptr(function_ptr_arg) { }
virtual void operator()() { (*function_ptr)(); }
void (*function_ptr)();
};
template <typename T>
struct MethodFunction : Function {
MethodFunction(T &obj_arg,void (T::*method_ptr_arg)())
: obj(obj_arg), method_ptr(method_ptr_arg)
{
}
virtual void operator()() { (obj.*method_ptr)(); }
T &obj;
void (T::*method_ptr)();
};
void f()
{
cout << "Called f()\n";
}
struct A {
void f() { cout << "Called A::f()\n"; }
};
int main(int argc,char **argv)
{
list<Function *> functions;
functions.push_back(new PlainFunction(f));
A a;
functions.push_back(new MethodFunction<A>(a,&A::f));
list<Function *>::iterator i = functions.begin();
for (;i!=functions.end();++i) {
(*(*i))();
}
while (!functions.empty()) {
Function *last_ptr = functions.back();
functions.pop_back();
delete last_ptr;
}
}
答案 2 :(得分:2)
让您的所有功能都实现Command Pattern.
您的列表变为
std::list<Command>
当您遍历列表时,您将调用每个列表项的Execute()方法。
例如,假设您有一个名为Commander的简单Command接口:
class Commander
{
public:
virtual ~Commander;
virtual void Execute();//= 0;
};
你想在列表中放置三个物品:灰狗,Gyrefalcon和女朋友。将每个包装在调用对象感兴趣的函数的Commander对象中。灰狗跑:
class RunGreyhound: public Commander
{
public:
void Execute()
{
mGreyhound->Run();
}
private:
Greyhound* mGreyhound;
};
Gyrefalcon苍蝇:
class RunGyrefalcon: public Commander
{
public:
void Execute()
{
mGyrefalcon->Fly( mGyrefalcon->Prey() );
}
private:
Gyrefalcon* mGyrefalcon;
};
女朋友吵了一声:
class RunGirlfriend: public Commander
{
public:
void Execute()
{
mGirlfriend->Squawk( mGirlfriend->MyJunk(), mGirlfriend->Mytrun() );
}
private:
Girlfriend* mGirlfriend;
};
填充列表中的Commander对象。现在你可以迭代它们并调用每个元素的Execute()方法:
std::list<Commander> cmdlist;
RunGreyhound dog;
cmdlist.push_back( dog );
RunGyrefalcon bird;
cmdlist.push_back( bird );
RunGirlfriend gurl;
cmdlist.push_back( gurl );
for ( std::list<Commander>::iterator rit = cmdlist.begin(); rit != cmdlist.end(); ++rit )
{
rit->Execute();
}