【问题标题】:Stack of class member functions but the class isn't known yet类成员函数堆栈,但该类尚不为人所知
【发布时间】:2011-07-03 09:51:41
【问题描述】:

我有一些难以解释的事情,所以我会尽力而为。我有一个 InstructionScreen 类,它显示箭头和文本块,解释每个按钮的作用等等。所以在 InstructionScreen 我有一堆成员函数,每个函数都会创建一些箭头和文本来解释不同按钮的作用。

InstructionScreen 将被子类化为 MenuInstructScreen、OptionsInstructScreen 等,在这些类中,我将创建自定义函数,这些函数将创建箭头和文本来解释它们的屏幕按钮。

问题在于在 InstructionScreen 中声明此堆栈,因为它将包含属于其子类的函数。我想我可以做到这一点,但我使用模板对吗?

简单来说,问题是如何声明一个堆栈,其中包含一个尚不存在的类的成员函数?

这个问题更容易理解&看看你看看这个简单的例子:

typedef class InstructionScreen;
typedef class MenuInstructScreen;
template <typename FooClass>
typedef void (FooClass::*MemberFuncPtr)();   // will be typedef void (MenuInstructScreen::*MemberFuncPtr)();


class InstructionScreen
{
     public:
         InstructionScreen() {}

         void runInstructions()
         {
              while ( !instructionStep.empty() )
              {
                  (this->*instructionStep.top())(); 
                  instructionStep.pop();
              }
         }

     protected:
          stack <MemberFuncPtr> instructionStep; 
};

class MenuInstructScreen : public InstructionScreen
{
    public:
       MenuInstructScreen() 
       {
          // Set instruction schedule
          instructionStep.push( &MenuInstructScreen::step2() ); 
          instructionStep.push( &MenuInstructScreen::step1() );              
       }

       void step1()
       {
            // create some widgets that point to buttons & widgets that contain text instructions 
       }

       void step2()
       {
            // create some widgets that point to buttons & widgets that contain text instructions 
       }

    private:

};

class OptionsInstructScreen : public InstructionScreen
{
    public:
       OptionsInstructScreen() 
       {
          // Set instruction schedule
          instructionStep.push( &OptionsInstructScreen::step2() ); 
          instructionStep.push( &OptionsInstructScreen::step1() );              
       }

       void step1()
       {
            // create some widgets that point to buttons & widgets that contain text instructions 
       }

       void step2()
       {
            // create some widgets that point to buttons & widgets that contain text instructions 
       }

    private:

};

【问题讨论】:

  • 指向成员函数的指针应该通过&amp;OptionsInstructScreen::step2获取。

标签: c++ function inheritance


【解决方案1】:

C++ 不允许模板化类型定义,但 C++11 通过Template Aliases 支持这一点。如果您的编译器不支持 C++11,您可以使用诸如 Boost.Function 之类的函子来实现相同的功能。

typedef boost::function<void()> Func;

由于您的 typedef 用于不带参数的成员函数,因此您可以使用 aboce 定义一个返回 void 且不接受任何参数的函子。尽管它不限于特定班级的成员。您可以使用以下方式将项目推送到派生类中的堆栈中:

stack.push(boost::bind(&MenuInstructScreen::step2, this));
stack.push(boost::bind(&MenuInstructScreen::step1, this));

您的原始示例现在看起来像这样......

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <stack>

class InstructionScreen
{
  public:
    void runInstructions()
    {
        while (!instructionStep.empty())
        {
            boost::function<void()> func = instructionStep.top();
            instructionStep.pop();

            func();
        }
    }

  protected:
    std::stack<boost::function<void()> > instructionStep;
};

class MenuInstructScreen : public InstructionScreen
{
  public:
    MenuInstructScreen()
    {
        instructionStep.push(boost::bind(&MenuInstructScreen::step2, this));
        instructionStep.push(boost::bind(&MenuInstructScreen::step1, this));
    }

    void step1()
    {
        //
    }

    void step2()
    {
        //
    }
};

class OptionsInstructScreen : public InstructionScreen
{
    public:
       OptionsInstructScreen() 
       {
          instructionStep.push(boost::bind(&OptionsInstructScreen::step2, this));
          instructionStep.push(boost::bind(&OptionsInstructScreen::step1, this));              
       }

       void step1()
       {
           //
       }

       void step2()
       {
           //
       }

    private:

};

int main() { } 

【讨论】:

    【解决方案2】:

    C++ 中没有“模板类型定义”。在 C++0x 中,您可以使用 模板别名,但目前对此的支持有限。

    为什么不简单地在你的基类中添加一个虚函数:

    virtual void steps() { };
    

    然后让每个派生类实现它:

    void steps() { step1(); step2(); }
    

    然后您可以将指向基类的指针存储在堆栈中,然后调用-&gt;steps()

    【讨论】:

      猜你喜欢
      • 2012-01-14
      • 2011-02-18
      • 2020-02-14
      • 2012-06-05
      • 2013-05-12
      • 1970-01-01
      • 2012-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多