Question:
Alternative to Global Variable? C++?
2010-05-25 07:54:13 UTC
Hello guys, I have a program that reads its settings from an ini file and stores them in a global variable.

I know that global variables are bad, but what else can I do so that all of my threads can read the programs settings that were load from the ini file? Is it better to just keep loading the settings when they are needed?

Please tell me what is a better way to do this so that all of my threads can access the value. Thanks.
Five answers:
2010-05-25 08:37:51 UTC
Global VARIABLES are bad, but if you're practically using them as CONSTANTS, you can just read them. In other words: it's OK if you read global variables all over the program, as long as you only modify their values in one place.
?
2016-10-02 06:02:20 UTC
Global Variable C
sumyounggai80
2010-05-25 08:47:49 UTC
Global variables aren't always bad, but they can be bad if used incorrectly in a multi-threaded environment.



The answer to your question depends on whether you will be changing these INI settings as your app is running. If you are then its probably better to read in the setting as needed.



If you're not going to change these settings then I would leave it in a global variable. There's no reason to load the file more than once.
Chris C
2010-05-25 08:43:43 UTC
Global variables are not bad when used properly.

Just don't abuse them. Some people use global variables to get information into a function and results out of a function, instead of simply passing a pointer to the function and allowing the function to modify the pointer's information as necessary.



I once wrote an application that utilized shared memory segments to store the information it read.

Then I wrote an interface into that shared memory, which is usually faster than accessing the disk.

In my case, I ran stored procedures, and stored the data into memory for later use, but it only ran the stored procedures upon initial load for speed purposes.



This can be done in both Windows and Unix (or flavors of it).



The best approach, is to provide a class which you interface with the INI file, registry, or shared memory. The reason for this, is that you can obviously change wherever it is stored, without affecting the operation of the program itself.

Kind of like the class below. Keep in mind that the implementation file for things like the "getIntAppSettings()", can simply look like this so that the reading/writing is all done in one or two methods.

int applicationINI::getIntAppSettings(char *appName, char *settingName)

{

   return (atoi(getAppSettings(appName, settingName));

}





Here's the sample class:

class applicationINI

{

   public:

      applicationINI();

      ~applicationINI();



      // Method to get an application specific setting

      char *getAppSetting(char *appName, char *settingName);

      int getIntAppSetting(char *appName, char *settingName);

      long getLongAppSetting(char *appName, char *settingName);

      double getDoubleAppSetting(char *appName, char *settingName);

      

      // Methods to set an application specific setting

      bool setAppSetting(char *appName, char *settingName, char *value);

      bool setAppSetting(char *appName, char *settingName, int value);

      bool setAppSetting(char *appName, char *settingName, long value);

      bool setAppSetting(char *appName, char *settingName, double value);



   private:

      int app

}



That way, your application doesn't care what device it is stored on, only the "applicationINI" class does, and handles all of that for you.





Oh, and the way that this was run, is that the item that stored the data in shared memory was a self-contained system tray application that provided that data.
?
2010-05-25 12:50:35 UTC
Like with everything in C++, there are many solutions:



1) Make your Configuration class a singleton. Each thread will then be able to obtain a reference to it by calling something like a static Configuration::instance() -- this is the very common (probably THE most common) object-oriented design pattern. This ensures that only one configuration ever exists, but threads can attempt accessing it before it loads a valid value from file (unless the file name is known before the beginning of main(), at static object construction time)



2) Pass a reference to your Configuration object as one of the arguments to your threads if they are functions or make a reference to Configuration one of the member variables of your thread class, if you're extending boost::thread or std::thread or some other thread class. This ensures that no thread can be started without configuration object existing (and assuming your configuration object loads the config in its constructor, this ensures that no thread will be started without a config).



3) Use a global object instance (a "variable"). C++ comes with several global objects (std::cin and std::cout, for example), and nobody is afraid of using them. Place it inside the same namespace as your configuration class (if you're using namespaces) or provide a static method that returns a reference to it, to make it more obvious in the source code where does that identifier come from (instead of suddenly reading from gConfig["timeout"] you'd be reading from Config::instance["timeout"] for example)



4) If your threads are able to exchange messages (as they are in our products), they can broadcast config request events and the config thread would respond to with the relevant values from the config file it loaded, or the config thread could even push updated config values to the threads (such as for changing config on-the-fly)



5) Another thing we use: answer this: do ALL of your threads need access to ALL of the config? Do ANY of your threads need to run before their config is known?

If no and no, how about you first read the config, then extract values necessary for each thread (for us config is XML and each thread's config is an XML node), and THEN start the threads, each with its own thread-specific config?


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Continue reading on narkive:
Loading...