我正在尝试存储函数的向量(或堆栈)。我的想法是,我有一系列功能,可以添加&将小部件移除到主窗口。我使用定时器闹钟&无论何时调用警报,我都会调用函数堆栈顶部的函数。
所以我的函数总是类型为void。我的问题/误解是如何dell stl :: stack of void functions&我该如何执行该功能?
class InstructionScreen
{
std::stack <void*> instructionSteps; // is this how I declare a stack of functions
void runTimerEvent()
{
if ( !instructionSteps.empty() )
{
// call the function at the top of the stack
// how do I call the function?
(*instructionSteps.top()); // is that how?
instructionSteps.pop();
}
}
void step1()
{
// here I create some widgets & add them to the main window
}
void step2()
{
// delete widgets from window
// create some different widgets & add them to the main window
}
void buildStack()
{
instructionSteps.push( (&step1()) ); // is this correct?
instructionSteps.push( (&step2()) );
}
};
答案 0 :(得分:3)
void*
指针不是合法函数指针。它应该是void (*)()
,使用typedef void (*stack_function)()
可以更好。
std::stack<stack_function> instructionSteps;
要将某些内容推入其中,您不会调用该函数(就像使用step1()
一样)并且您当然不会像使用{那样使用返回的地址(无论如何都是无效的) {1}},您只需单独使用函数名称:
&step1()
要从堆栈顶部调用内容,您实际上需要执行调用:
instructionSteps.push(step1); // the & can be omitted for free functions
instructionSteps.push(&step2); // equivalent to the above, only a different function
也可以省略取消引用,因为这里需要花费很长时间才能解释,搜索SO。 :)
(*instructionSteps.top())();
// you missed that -- ^^
答案 1 :(得分:2)
静态函数指针的语法如下:
void (*FuncPtr)();
对于成员指针,您必须使用以下语法:
void (class::*FuncPtr)();
如果您的功能不需要功能成为会员功能,那就更清洁了。一旦你弄明白你需要什么样的功能,最简单的方法就是输入这些函数:
typedef void(*FuncPtrType)();
typedef void(Class::*MemberFuncPtrType)();
现在你可以简单地声明一个带有函数指针的堆栈,如下所示:
std::stack <FuncPtrType> funcPtrStack;
std::stack <MemberFuncPtrType> memberFuncPtrStack;
要获得指向函数的指针,只需使用“&amp;”运算符就像你在C ++中获取任何其他数据类型的地址一样:
FuncPtrType funcPtr = &staticFunc; // Somewhere "void staticFunc()" is defined
MemberFuncPtrType memberFuncPtr = &Class::MemberFunc; // Somewhere void "Class::MemberFunc()" is defined
要实际调用函数指针,可以使用“*”运算符从指针中获取数据(就像C ++中的任何其他数据类型一样)。唯一棘手的问题是对于成员函数,他们需要一个指向类的指针,这使得它的使用非常尴尬。这就是我推荐使用静态函数的原因。无论如何,这是语法:
(*funcPtr)(); // I just called a function with a pointer!
(this->*memberFuncPtr)(); // I just wrote some ugly code to call a member function
完成所有这些后,以下代码现在应该有意义了:
std::stack <MemberFuncPtrType> memberFuncPtrStack; // Declaring the stack
memberFuncPtrStack.push( &Class::MemberFunc ); // Pushing a function
(ClassPtr->*memberFuncPtrStack.top())(); // Calling the function with ClassPtr
答案 2 :(得分:1)
声明typedef
并制作vector
/ stack
:
typedef void (*funcptr)();
std::stack<funcptr> instructionSteps;
用法:
instructionSteps.push(&step1);
instructionSteps.push(&step2);
见demo here。 执行:
instructionSteps.top()();
答案 3 :(得分:1)
提示:使用Boost.Function,它更容易。它不仅可以存储具有正确类型的函数,还可以存储可以以相同方式调用的任何其他函数。
std::stack<boost::function<void()> instructionSteps;
int foo() { return 42; }
instructionSteps.push(foo); // Close enough - return value will be discarded.
答案 4 :(得分:0)
typedef void (*fptr)();
class InstructionScreen
{
std::stack <fptr> instructionSteps;
答案 5 :(得分:0)
我会typedef
函数指针让你的生活更轻松:
typedef void(*voidFunctionPointer)(); // Assuming here that the functions take no arguments.
std::stack<voidFunctionPointer> instructionSteps; // This is very different from <void*>.
// The latter is merely a stack of void pointers.
调用top函数的一种方法是:
voidFunctionPointer functionToCall = instructionSteps.top();
functionToCall();
如果你想在没有额外声明的情况下这样做,我认为这应该有效。如果我错了,请纠正我。
instructionSteps.top()();
要构建堆栈,只需使用没有任何尾随括号的函数名称。
instructionSteps.push(step1);
instructionSteps.push(step2);
// ...