0

I am working on a self organizing map program. For it i am trying to create a way that I can centralize all the user/developer variables that can be set. I have been trying to use a Config.h/.cpp files but am unsure if this is the correct/best method.

It seems if I don't put things in in just the right way it errors on compile.

The question is the best/correct way to centralize variables that must be changed in between compilation and runs?

Config.h

#ifndef CONFIG_H_
#define CONFIG_H_


class Config{

public:


    static const std::string outputFileLocation;// 
    static const std::string inputFilename;// 
    static const std::string outputFileExt;//

    unsigned int vectorLength = 3;//RGB


    //VARIBLE USED IN SOM CLASS
    static const int NODE_GRID_HEIGHT = 100;
    static const int NODE_GRID_WIDTH = 100;


};

#endif /* CONFIG_H_ */

Config.cpp

#include "Config.h"

//location to store output soms at it is iterated through
std::string Config::outputFileLocation = "/home/projectFiles/testMedia/results/mySom_";

//extension to put on output soms.
std::string Config::outputFileExt = ".jpeg";

////starting rgb image file to proccess
std::string Config::inputFilename = "/home/projectFiles/testMedia/yellowColor3.jpg";


////Length of muliti-dimensional data point. ie. a pixel.
unsigned int Config::vectorLength = 3;
aaron burns
  • 267
  • 4
  • 15
  • In c++ I'm pretty sure you have to define `const` variables as soon as you declare them; you may want to abandon the `.cpp` file and just use a header file. Can you provide more details about the compiler errors you get? – Jason Baker Aug 29 '14 at 19:16
  • 1
    What is your question? – Anton Savin Aug 29 '14 at 19:16
  • The question is the best/correct way to centralize variables that must be changed in between compilation and runs? – aaron burns Aug 29 '14 at 19:21

2 Answers2

1

It's a valid approach to keep the config in a distinct class. So you will be able to define a constructor for a default configuration, as well as config load and save methods.

However in you code there are minor consistency issues.

If you declare :

   static const std::string outputFileLocation;  // you said const  

Then you should define it as a const :

   const std::string Config::outputFileLocation = "/home/projectFiles/testMedia/results/mySom_";

Conversely, if you define a non static data member:

   unsigned int vectorLength = 3;   //You already intialise it here 

You shall not redefine it as you did. This would only be necessary for statics.

However, I wonder why you make the statics const. This requires that they are initialised (either as you did, if they are static, or as part of the constructor for ordinary members) and they may not change afterwards. This prevents your from changing the configuration, for example when loading a config file at startup.

Additional thoughts

Once you have your configuration class, you can decided easily which variable is fixed at compilation, and which should be initialised dynamically. Dynamically could for example be:

  • read a configuration file (see: this SO question).

  • get some variables through system environment (see getenv())

  • system specific approaches, but this woudld not be portable so should be considered with care (for windows, it's usual for example to use the registry)

  • using command line arguments passed to main().

Community
  • 1
  • 1
Christophe
  • 68,716
  • 7
  • 72
  • 138
0

I deduce you are using your code to run experiments, since you need to change variables values between compilations and runs. One simple way I have done this in the past is by centralizing everything inside an unnamed namespace in a header file. This way, you may drop the static declarations, and just #include the config file where you need.

Something like this.

Configs.h

#ifndef CONFIG_H_
#define CONFIG_H_

namespace{

    const std::string outputFileLocation = "something";// 
    const std::string inputFilename = "something";// 
    const std::string outputFileExt = "something";//

    unsigned int vectorLength = 3;//RGB    

    //VARIBLE USED IN SOM CLASS
    const int NODE_GRID_HEIGHT = 100;
    const int NODE_GRID_WIDTH = 100;

};
#endif

Note this might not be the best solution, but is simple and effective. Depending on the goals of your project, you might need to consider a more elegant solution.

Another suggestion

Assuming my deduction is correct, reading those values from a configuration text file would also be a good option. You would not need to recompile between runs, which may be very time consuming if you have a large project, and many other files depend on that single configuration one.