I am trying to write some code which to the best of my knoledge is an example of a state machine.
What I have done so far is:
#include <map>
#include <iostream>
class StateInstance
{
std::string m_string;
public:
StateInstance(const std::string& string)
: m_string{string}
{
}
std::string Get() const
{
return m_string;
}
}instance_a("hello world"), instance_b("bring me coffee");
enum class StateInstanceOption
{
STATE_INSTANCE_A,
STATE_INSTANCE_B
}gCurrentState{StateInstanceOption::STATE_INSTANCE_A}; // global variable to hold current state "pointer" (really a flag)
class StateInstanceMapper
{
std::map<StateInstanceOption, const StateInstance&> m_map;
public:
StateInstanceMapper()
{
m_map.insert(std::pair<StateInstanceOption, const StateInstance&>(StateInstanceOption::STATE_INSTANCE_A, instance_a));
m_map.insert(std::pair<StateInstanceOption, const StateInstance&>(StateInstanceOption::STATE_INSTANCE_B, instance_b));
}
const StateInstance& DoMap(/*const StateInstanceOption opt*/) const
{
return m_map.at(/*opt*/ gCurrentState);
}
}mapper_instance;
int main()
{
std::cout << mapper_instance.DoMap(/*gCurrentState*/).Get() << std::endl;
gCurrentState = StateInstanceOption::STATE_INSTANCE_B;
std::cout << mapper_instance.DoMap(/*gCurrentState*/).Get() << std::endl;
return 0;
}
This works fine, however during the runtime of my program I only want there to exist a single state.
- I want a way to prevent the user creating another instance of
StateInstance
,StateInstanceOption
andStateInstanceMapper
For the example of a function, (in C), I would make the function static, and put the function in a seperate header, thus preventing it from being seen in other files.
Is there anything I can do to stop the end user creating more instances of these objects?
Since this question was disruptively closed so rappidly I cannot add an answer as an answer, however here is "the answer to this question"
#include <map>
#include <iostream>
class StateInstance
{
std::string m_string;
public:
// somewhat inconveniently, have to create an entirely new function for each possible instance of the state
static StateInstance& get_instance_a()
{
static StateInstance instance_a("hello world");
return instance_a;
}
static StateInstance& get_instance_b()
{
static StateInstance instance_b("bring me coffee");
return instance_b;
}
private:
StateInstance(const std::string& string)
: m_string{string}
{
}
StateInstance(const StateInstance &) = delete;
StateInstance& operator=(const StateInstance&) = delete;
public:
std::string Get() const
{
return m_string;
}
}; // instance_a("hello world"), instance_b("bring me coffee");
enum class StateInstanceOption
{
STATE_INSTANCE_A,
STATE_INSTANCE_B
}gCurrentState{StateInstanceOption::STATE_INSTANCE_A}; // global variable to hold current state "pointer" (really a flag)
class StateInstanceMapper
{
std::map<StateInstanceOption, const StateInstance&> m_map;
public:
static StateInstanceMapper& getInstance()
{
static StateInstanceMapper instance;
return instance;
}
private:
StateInstanceMapper()
{
m_map.insert(std::pair<StateInstanceOption, const StateInstance&>(StateInstanceOption::STATE_INSTANCE_A, StateInstance::get_instance_a()));
m_map.insert(std::pair<StateInstanceOption, const StateInstance&>(StateInstanceOption::STATE_INSTANCE_B, StateInstance::get_instance_b()));
}
StateInstanceMapper(const StateInstanceMapper &) = delete;
StateInstanceMapper& operator=(const StateInstanceMapper &) = delete;
public:
const StateInstance& DoMap(/*const StateInstanceOption opt*/) const
{
return m_map.at(/*opt*/ gCurrentState);
}
}; //mapper_instance;
int main()
{
//std::cout << mapper_instance.DoMap(/*gCurrentState*/).Get() << std::endl;
std::cout << StateInstanceMapper::getInstance().DoMap().Get() << std::endl;
gCurrentState = StateInstanceOption::STATE_INSTANCE_B;
//std::cout << mapper_instance.DoMap(/*gCurrentState*/).Get() << std::endl;
std::cout << StateInstanceMapper::getInstance().DoMap().Get() << std::endl;
return 0;
}