dimanche 29 mai 2016

Converting Java State Machine Example to C++, Stuck on last hurdle

Background

I'm getting back into C++ after a bit of a Haitus. I never was fantastic at C or C++, but I considered myself to have a bit of a working knowledge.

I set off with a simple goal. Convert a Java state-machine example to C++ I Think the problem is in passing a new State<CeilingFanPullChain>, I've added empty stub constructors to the classes that inherit from my template interface (used to get around dependency issue that should probably be solved by altering the design).

As a requirement from myself to myself, I don't want to use pre-processor magic, which is what a lot of online examples seem to use. I also do not want to use a switch statement. I'd like to make this as Object-Oriented as possible.

#include <iostream>
#include <string>

// The CeilingFanPullChain class is now a wrapper
// that delegates to its m_current_state reference.
// Each clause from the "before" case statement is
// now captured in a State derived class.

// For this simple domain, the State pattern is
// probably over-kill.


template <class T>
class State {
public:
    virtual void pull( T &wrapper ) = 0;
};

class CeilingFanPullChain {

private:
    State<CeilingFanPullChain>* m_current_state;

public:
    CeilingFanPullChain() {
        m_current_state = new Off();
    }
    void set_state( State<CeilingFanPullChain>* s ) {
        m_current_state = s;
    }
    void pull() {
        m_current_state->pull( *this );
    }
};

class Off: public State<CeilingFanPullChain> {
public:
    Off() {}
    void pull( CeilingFanPullChain &wrapper ) {
        wrapper.set_state( new Low() );
        std::cout << "   low speed\n";
    }
};

class Low: State<CeilingFanPullChain> {
public:
    Low() {}
    void pull( CeilingFanPullChain &wrapper ) {
        wrapper.set_state( new Medium() );
        std::cout << "   medium speed\n";
    }
};

class Medium: State<CeilingFanPullChain> {
public:
    Medium() {}
    void pull( CeilingFanPullChain &wrapper ) {
        wrapper.set_state( new High() );
        std::cout << "   high speed\n";
    }
};

class High: State<CeilingFanPullChain> {
public:
    High() {}
    void pull( CeilingFanPullChain &wrapper ) {
        wrapper.set_state( new Off() );
        std::cout << "   turning off\n";
    }
};

std::string get_line() {
    std::string line_tmp;
    std::getline(std::cin, line_tmp);
    return line_tmp;
}

int main() {
    CeilingFanPullChain* chain = new CeilingFanPullChain();
    while (true) {
        std::cout << "Press \n";
        get_line();
        chain->pull();
    }
    return 0;
}

Error Output

ceiling-fan.cpp: In constructor ‘CeilingFanPullChain::CeilingFanPullChain()’:
ceiling-fan.cpp:26:31: error: expected type-specifier before ‘Off’
         m_current_state = new Off();
                               ^
ceiling-fan.cpp: In member function ‘virtual void Off::pull(CeilingFanPullChain&)’:
ceiling-fan.cpp:40:32: error: expected type-specifier before ‘Low’
         wrapper.set_state( new Low() );
                                ^
ceiling-fan.cpp: In member function ‘virtual void Low::pull(CeilingFanPullChain&)’:
ceiling-fan.cpp:49:32: error: expected type-specifier before ‘Medium’
         wrapper.set_state( new Medium() );
                                ^
ceiling-fan.cpp: In member function ‘virtual void Medium::pull(CeilingFanPullChain&)’:
ceiling-fan.cpp:58:32: error: expected type-specifier before ‘High’
         wrapper.set_state( new High() );

Aucun commentaire:

Enregistrer un commentaire