Maintaining Program State Variables

Let's say I would like to maintain variables, such as:

1
2
3
bool usbConnected;     //Whether the USB connection has been established
int programState;     //Which state the program is in (i.e. busy, waiting, menu, etc.)
int progress;     //Some variable to keep track of program progress 
etc.

How would I keep track of this? I've read up and have been cautioned against using the Singleton pattern and static classes. Would there be something else appropriate for this?
Singletons are not evil they are just easy to abuse.
Just one suggestion:

Wrap the state variables by a state class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

#include <memory>

enum ProgramState { BUSY, WAITING, MENU};

class Instance
{
public:
  virtual bool usbConnected() const = 0;
  virtual ProgramState getProgramState() const = 0;
  virtual int getProgress() const = 0;
};

// class DerivedInstance...

int main()
{
  std::shared_ptr<Instance> instance(new DerivedInstance());
  // pass instance to a GUI or whatever front-end that you're using.
}
Last edited on
@Luc What's the use in wrapping Instance in DerivedInstance?
What it gives you is an "interface". It facilitates component interchange. Say at some point you want to change the behavior of your GUI's back-end (which was previously DerivedInstance).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Instance
{
public:
  virtual bool usbConnected() const = 0;
  virtual ProgramState getProgramState() const = 0;
  virtual int getProgress() const = 0;
};

class USBConnection;

class DerivedInstance : public Instance
{

  USBConnection connection;

  virtual bool usbConnected() const
  {
    return connection.isConnected();
  }
  virtual ProgramState getProgramState() const {/* ... */ }
  virtual int getProgress() const {/* ... */ }
}

class AnotherDerivedInstance : public Instance
{
  std::list<USBConnection> connections;

  virtual bool usbConnected() const
  {
    for(std::list<USBConnection>::const_iterator iter = connections.begin(); iter != connections.end(); ++iter)
    {
      if(iter->isConnected())
      {
        return true;
      }
    }
    return false;
  }

  virtual ProgramState getProgramState() const {/* ... */ }
  virtual int getProgress() const {/* ... */ }
}

class AwesomeGUI;

int main()
{
  AwesomeGUI gui1(std::shared_ptr<Instance>(new DerivedInstance()));
  AwesomeGUI gui2(std::shared_ptr<Instance>(new AnotherDerivedInstance()));
  // The same AwesomeGUI can be used for both derived types without any code duplication.
}


It's a pattern that I use very frequently in my projects. Hope it helps.

P.S. The same effect can be achieved through templates with a negligible performance boost, but I usually prefer to use an inheritance setup. It's all a matter of personal style.
Last edited on
Topic archived. No new replies allowed.