构建并执行一堆 void 函数

Build & execute a stack of void functions

本文关键字:一堆 void 函数 执行 构建      更新时间:2023-10-16

我正在尝试存储函数的向量(或堆栈(。这个想法是我有一系列功能可以在主窗口中添加和删除小部件。我使用计时器警报,每当调用警报时,我都会调用函数堆栈顶部的函数。

所以我的函数将始终是 void 类型。我的问题/误解是如何维护一个 stl::stack of void 函数以及如何执行该函数?

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()) );  
  }
};

void*指针不是合法函数指针。它应该是void (*)()的,可以用typedef void (*stack_function)()做得更好。

std::stack<stack_function> instructionSteps;

要将某些内容推送到其中,您不会调用函数(就像对step1()所做的那样(,并且您当然不会像&step1()那样获取返回的地址(无论如何都是无效的(,您只需单独使用函数名称:

instructionSteps.push(step1); // the & can be omitted for free functions
instructionSteps.push(&step2); // equivalent to the above, only a different function

要从堆栈顶部调用内容,您实际上需要执行调用:

(*instructionSteps.top())();
//    you missed that -- ^^

取消引用也可以省略,原因需要很长时间才能在这里解释,搜索 SO. :)

instructionSteps.top()();

静态函数指针的语法如下所示:

void (*FuncPtr)();

对于成员指针,必须使用以下语法:

void (class::*FuncPtr)();

如果您的函数不需要函数成为成员函数,则要干净得多。一旦你弄清楚你需要什么样的函数,最简单的方法是像这样类型定义这些函数:

typedef void(*FuncPtrType)();
typedef void(Class::*MemberFuncPtrType)();

现在,您可以简单地使用函数指针声明一个堆栈,如下所示:

std::stack <FuncPtrType> funcPtrStack;
std::stack <MemberFuncPtrType> memberFuncPtrStack;

要获取指向函数的指针,您只需使用"&"运算符,就像获取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

声明一个typedef并对其进行vector/stack

typedef void (*funcptr)();
std::stack<funcptr> instructionSteps;

用法:

instructionSteps.push(&step1);
instructionSteps.push(&step2);  

在此处查看演示。执行:

instructionSteps.top()();

提示:使用 Boost.Function,它要容易得多。它不仅会存储具有精确正确类型的函数,还会存储可以以相同方式调用的任何其他函数。

std::stack<boost::function<void()> instructionSteps;
int foo() { return 42; }
instructionSteps.push(foo); // Close enough - return value will be discarded.
typedef void (*fptr)();
class InstructionScreen
{
  std::stack <fptr> instructionSteps; 

我会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);
// ...