first time in Stackoverflow! I am quite new in C++ and OOP and I am currently struggling with a problem when trying to design a StateChart in C++.
I have found some documentation explaining how to create a State Machine with n-states and an example of code simulating the transitions Red-Green-Yellow in a traffic light.
I report the code below:
Header
class TLState
{
public:
virtual void Handle() = 0;
};
class TLNetTraffic
{
private:
TLState* _state;
public:
TLNetTraffic();
void setState ( TLState* state );
void Handle();
};
class TLRed: public myTLState
{
private:
TLNetTraffic* _context;
public:
TLRed(TLNetTraffic* context);
void Handle();
};
class TLGreen: public TLState
{
private:
TLNetTraffic* _context;
public:
TLGreen(TLNetTraffic* context);
void Handle();
};
class TLYellow: public TLState
{
private:
TLNetTraffic* _context;
public:
TLYellow(TLNetTraffic* context);
void Handle();
};
cpp
#include "classes.h"
#include <iostream>
TLNetTraffic::TLNetTraffic()
{
_state = new TLRed(this);
}
void TLNetTraffic::setState ( TLState* state )
{
_state = state;
}
void TLNetTraffic::Handle ()
{
_state->Handle();
}
TLRed::TLRed(TLNetTraffic* context): _context(context) {}
void TLRed::Handle()
{
std::cout << "Red Light" << std::endl;
_context->setState( new TLGreen(_context) );
}
TLGreen::TLGreen(TLNetTraffic* context): _context(context) {}
void TLGreen::Handle()
{
std::cout << "Green Light" << std::endl;
_context->setState( new TLYellow(_context) );
}
TLYellow::TLYellow(TLNetTraffic* context): _context(context) {}
void TLYellow::Handle()
{
std::cout << "Yellow Light" << std::endl;
_context->setState( new TLRed(_context) );
}
There is my question: I would like to extend such example with sub-states for each upper state, for instance Red_1, Red_2, Red_3, Green_1, Green_2, Green_3, Yellow_1, Yellow_2, Yellow_3...
Now, the easiest thing I have in mind is to "consider" all the states at the same level and to use the structure reported above. Personally, I do not like this solution and I was wondering whether a nicer design could be implemented. I tried to modify the code as follows (I report only the "red" class):
class myTLState
{
public:
virtual void Handle() = 0;
};
class myTLState_internal //NEW VIRTUAL CLASS
{
public:
virtual void Handle() = 0;
};
class myTLNetTraffic
{
private:
myTLState* _state;
public:
myTLNetTraffic();
void setState ( myTLState* state );
void Handle();
};
class myTLRed: public myTLState
{
private:
myTLNetTraffic* _context;
myTLState_internal* _internal_state; //NEW POINTER TO THE NEW VIRTUAL CLASS
public:
myTLRed(myTLNetTraffic* context);
void Handle();
void setState ( myTLState_internal* _internal_state );
};
class myTLRed_internal1: public myTLState_internal
{
private:
myTLRed* _internal_context;
public:
myTLRed_internal1(myTLRed* context);
void Handle();
};
class myTLRed_internal2: public myTLState_internal
{
private:
myTLRed* _internal_context;
public:
myTLRed_internal2(myTLRed* context);
void Handle();
};
I added in the cpp the following:
myTLRed::myTLRed(myTLNetTraffic* context): _context(context)
{
_internal_state = new myTLRed_internal1(this);
}
myTLRed_internal1::myTLRed_internal1(myTLRed* context): _internal_context(context){}
I get the following error message: undefined reference to 'vtable for myTLRed_internal1'
Honestly, no idea neither what that is nor if this is the right way. Any help would be really appreciated. Thanks a lot and sorry for the long post.
Aucun commentaire:
Enregistrer un commentaire