#include <iostream>
using namespace std;

class Machine
{
   class State *current;
   class State *nextstate; 
   void check_transition(); 
public:
    Machine();
    void setCurrent(State *s)
    {
    	nextstate = s; 
        //current = s;
    }
    void set_on();
    void set_off();
};

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

void Machine::check_transition() { 
   	   if (nextstate) {
   	   	   swap (current, nextstate);
   	   	   delete nextstate;  // this contains the former current  
   	   	   nextstate = nullptr; 
   	   }
   }

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

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

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

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

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

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

int main()
{
  void(Machine:: *ptrs[])() = 
  {
    &Machine::set_off, &Machine::set_on
  };
  Machine fsm;
  int num;
  cout << "Enter 0/1: ";

  while (cin >> num)
  {
     
    (fsm.*ptrs[num])();
   cout << "Enter 0/1: ";
  }
}