1

I'm moving an embedded program from C# to C++ and have been struggling to figure out how to create an array of classes. The program uses a pretty standard "Gang of Four" state pattern. Each of the states is a class that inherits from the base class StateBase. All the state classes reside in an array that I can index as needed. I don't get any errors in the VisualGDB error list but when I compile the program I get this

undefined reference to 'StateBase::StateBase()'

I'm not very experienced in C++ so there's a good chance I'm doing something fundamentally dumb and will appreciate any help.

Here's the base class StateBase:

class StateBase
{
public:
    StateBase();
    virtual void doStateEntryActions();
    virtual void doStateActions();
    virtual StateNames checkEvents();
    virtual void doStateExit(bool timeout);
};

Here's an example of one of the state classes that inherits from StateBase

class Recovery : public StateBase
{
public: 
    Recovery()
    {
        cout << "Recovery constructor" << endl;
    };
    
private:
    void doStateEntryActions()
    {
        cout << "Recovery: doing state entry actions" << endl;
    }
    void doStateActions()
    {
        cout << "Recovery: doing state actions" << endl;
    }
    StateNames checkEvents()
    {
        cout << "Recovery: checking events" << endl;
        return (recovery);
    }
    void doStateExit(bool timeout)
    {
        if (timeout)
            cout << "Recovery: doing state exit with timeout" << endl;
        else
            cout << "Recovery: doing state exit no timeout" << endl;
    }
};

Here's how I define the array

StateBase *stateArray[numStates];
stateArray[recovery] = new Recovery();
stateArray[findNeutral] = new FindNeutral();
stateArray[descend] = new Descend();

And here's how the state machine works:

while (runMission)
{
    if (doStateEntry)
    {
        stateArray[currentState]->doStateEntryActions();
        doStateEntry = false;
    }
    
    stateArray[currentState]->doStateActions();
    nextState = stateArray[currentState]->checkEvents();
    if (nextState != currentState)
    {
        stateArray[currentState]->doStateExit(false);
        currentState = nextState;
    }
}

Thanks is advance for any help.

Gene
  • 65
  • 6
  • You forgot to define the constructor, anywhere. – Sam Varshavchik Oct 11 '20 at 16:18
  • Sam - That helps but I still haven't put it all together. Now I'm defining the StateBase constructor in-line like this: StateBase(){}; and the derived class constructor also in-line like this Recovery() : StateBase() { cout << "Recovery constructor" << endl; }; and now I get this error after building: "undefined vtable for StateBase. I've looked hard at the suggested answers and a whole bunch of other answers on the web and googled "undefined vtable" but still haven't figure out what I'm doing wrong. Thanks for all the help. – Gene Oct 11 '20 at 18:33
  • If there's something C++ related that you don't understand, a good C++ textbook is your best resource. Unfortunately, stackoverflow.com is not a replacement for a C++ textbook. – Sam Varshavchik Oct 11 '20 at 18:36
  • I've got 2 of the C++ books by Stroustrup but I'm still missing something. I do spend a fair amount of time trying to figure this stuff out on my own and only resort to posting questions as a last resort. – Gene Oct 11 '20 at 18:38
  • The error means that not all of the virtual methods are defined either, same problem. All class methods must be defined, somewhere. That's the only way that C++ works. – Sam Varshavchik Oct 11 '20 at 18:49
  • I've got it running now. Many, many thanks Sam. – Gene Oct 11 '20 at 19:50

0 Answers0