該列表必須包含函數,它們可能來自不同的命名空間,甚至是實例化類的方法。
這個列表將被迭代並調用所有的函數和方法。如果他們也可以包含參數將會很好。需要某種方式將函數存儲在列表中,然後調用它們
我在考慮使用std :: vector,但我懷疑在猜測中我是遠遠不夠的。
你推薦我什麼方法?歡迎所有幫助。
該列表必須包含函數,它們可能來自不同的命名空間,甚至是實例化類的方法。
這個列表將被迭代並調用所有的函數和方法。如果他們也可以包含參數將會很好。需要某種方式將函數存儲在列表中,然後調用它們
我在考慮使用std :: vector,但我懷疑在猜測中我是遠遠不夠的。
你推薦我什麼方法?歡迎所有幫助。
有所有的功能實現Command Pattern.
您的列表變成
std::list<Command>
當你遍歷列表,您可以調用每個列表的execute()方法項目。
例如,假設你有一個名爲指揮官一個簡單的命令界面:
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;
};
的東西,在你的列表中的指揮官對象。現在你可以在它們之間迭代並調用每個元素的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();
}
我只是找不到任何關於此的文檔。你能告訴我一個最小的代碼讓我明白嗎? – 2011-09-23 20:55:00
我用一個非常簡單的例子擴展了我的答案。 – Gnawme
如果您不想使用現有解決方案(如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;
}
}
你可以使用std ::函數和std ::綁定,如果你的編譯器已經支持它。
#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;
}
我們可以有更多關於這些功能的細節嗎? (即可能的返回類型和參數)另外,我認爲你的意思是「迭代」而不是「遞歸」。 – quasiverse
或者也許「遍歷」 – Colin
幾年前我說過使用boost:函數,但是現在我不知道... – Colin