需要澄清状态模式的工作原理

时间:2014-04-14 03:25:44

标签: c++ design-patterns state

#include <iostream>
using namespace std;
class Machine
{
  class State *current;
  public:
    Machine();
    void setCurrent(State *s)
    {
        current = s;
    }
    void on();
    void off();
};

class State
{
  public:
    virtual void on(Machine *m)
    {
        cout << "   already ON\n";
    }
    virtual void off(Machine *m)
    {
        cout << "   already OFF\n";
    }
};

void Machine::on()
{
  current->on(this);
}

void Machine::off()
{
  current->off(this);
}

class ON: public State
{
  public:
    ON()
    {
        cout << "   ON-ctor ";
    };
    ~ON()
    {
        cout << "   dtor-ON\n";
    };
    void off(Machine *m);
};

class OFF: public State
{
  public:
    OFF()
    {
        cout << "   OFF-ctor ";
    };
    ~OFF()
    {
        cout << "   dtor-OFF\n";
    };
    void on(Machine *m)
    {
        cout << "   going from OFF to ON";
        m->setCurrent(new ON());
        delete this;
    }
};

void ON::off(Machine *m)
{
  cout << "   going from ON to OFF";
  m->setCurrent(new OFF());
  delete this;
}

Machine::Machine()
{
  current = new OFF();
  cout << '\n';
}

int main()
{
  void(Machine:: *ptrs[])() = 
  {
    Machine::off, Machine::on
  };
  Machine fsm;
  int num;
  while (1)
  {
    cout << "Enter 0/1: ";
    cin >> num;
    (fsm. *ptrs[num])();
  }
}

有一些我不太了解的代码。

首先,这究竟是做什么的?

(fsm. *ptrs[num])();

看起来它正在调用状态的默认构造函数,但我并不完全确定。另外,我不明白调用on和off方法的位置。我认为对象机器是on和off方法的调用对象,但我甚至不确定。

最后,我们为什么要摧毁这个?

void on(Machine *m)
{
    cout << "   going from OFF to ON";
    m->setCurrent(new ON());
    delete this;
}

仅用于内存管理吗?

1 个答案:

答案 0 :(得分:1)

我用两个函数指针和一些注释重写了代码: 而不是函数指针数组,我使用了2个diff指针,我正在使用if else来做出切换状态的决定。

主:

int main()
{
  void (Machine::*offptr)() = &Machine::off;    //offptr is a member funct pointer that now points to Machine::off function
  void (Machine::*onptr)() = &Machine::on;      //onptr is a member funct pointer that now points to Machine::on function
  Machine fsm;
  int num;
  while (1)
  {
      cout<<"Enter 0/1: ";
      cin>>num;
      if( num == 0 )
      {
          (fsm.*offptr)();          //Here your are calling the function pointed to by the offptr (i.e., Machine::off) using the pointer
      }
      else if( num == 1 )
      {
          (fsm.*onptr)();           //Here your are calling the function pointed to by the onptr (i.e., Machine::on) using the pointer
      }
  }

}

在您的示例中,所有决定都是在指针数组索引的帮助下完成的。因此,如果用户按下0,将调用ptrs[0]指向的函数,对于1,将调用ptr[1]指向的函数。但由于没有检查以确保用户输入0/1,如果用户输入0或1以外的其他内容,程序将崩溃。

void on(Machine *m)
{
    cout << "   going from OFF to ON";
    m->setCurrent(new ON());    //Here you are changing the state of the machine from OFF to ON (Note: call comes to this function only if the previous state was OFF).
    delete this;                //The previous state instance (OFF state pointed by this pointer) of the machine is no more required. So you are deleting it.
}