Using Visual Studio C++ with MFC. I'm trying to figure out what would be a good way to store application/program settings. I'm not referring to their persistent storage but to the data structure used in code to hold the settings.
I created a static class called Settings that has several static methods and also nested classes to partition the settings. For example:
class Settings
{
public:
    Settings(void);
    ~Settings(void);
    static void SetConfigFile(const char * path);
    static CString GetConfigFilePath();
    static void Load();
    static void Save();
    class General
    {
    public:
        static CString GetHomePage();
        static void SetHomePage(const char * url);
    private:
        static int homePageUrl_;
    };
private:
    static CString configFilePath_;
};
Then I can access my settings throughout my code like:
Settings::General::GetHomePage();
Now I'm getting into unit testing and I'm starting to realize that static classes are undesirable. So I want to turn this into an instance based class. But I'll have to manage the nested class instances which is trivial but still seems a little cumbersome for testing. The whole intention of the nested classes is simply to group the settings into logical groups. I'm debating whether a string-based settings class would be better, something like settings->get("General.HomePage") although I think I prefer the strong typing of dedicated accessor methods.
So to get to my question what is a good data structure to hold program configuration/settings that supports straightforward unit testing?
You can do this if it works for you. You can ditch the enum and go to const strings or even free-form strings. The enum doesn't really have to be defined in the class either. There are lots of ways to do it.
Another class could do something similar with multiple instances using a template to define the enum type if you wanted to implement categories.
Just an idea.
#include "stdafx.h"
#include <map>
#include <string>
#include <iostream>
using namespace std;
class Settings
{
public:
  typedef enum
  {
    HomePageURL,
    EmailAddress,
    CellPhone
  } SettingName;
private:
  typedef map<SettingName, string> SettingCollection;
  SettingCollection theSettings;
public:
  string& operator[](const SettingName& theName)
  {
    return theSettings[theName];
  }
  void Load ()
  {
    theSettings[HomePageURL] = "http://localhost";
  }
  void Save ()
  {
    // Do whatever here
  }
};
int _tmain(int argc, _TCHAR* argv[])
{
  Settings someSettings;
  someSettings.Load ();
  cout << someSettings [Settings::SettingName::HomePageURL] << endl;
    return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With