How to create a global parameters object - c++

Here's a common, simple task: Read configuration settings from a configuration file, save the settings (e.g. as a hash) in an object, access this object from various objects that need to access the configuration parameters.
I found this implementation for the ConfigFile class implementation and it works. My question is: what is the best way to make an instance of this class available from my other classes and be thread safe, avoid static initialization order fiasco, etc.
My current approach is to construct it in main() using
// Read face detection related parameter values from the configuration file.
string configFileName = "detection_parameters.txt";
try {
parameters = ConfigFile( configFileName );
}
catch(ConfigFile::file_not_found) {
cerr << "configuration file not found: " << configFileName << endl;
exit(-1);
}
and then make parameters a global variable. But I also read that singletons should be used instead of global variables. How can the singleton be instantiated with the file name?
This must be such a common task that I think there must be a generally accepted good way of doing it? I would appreciate if someone can point me to it.
Thanks,
C

If you're going to roll-your-own, I would recommend using the Singleton design pattern for your configuration class.
Have the class itself store a static pointer of its own type, and the constructor be private so one would be forced to use the static getter to get the one instance of the class.
so a mock-up (that may not compile, an is missing the fun Config functionality, but should illustrate the point)
class Config
{
public:
static Config * getConfig();
static void setConfigFileName(string filename);
private:
Config();
static string m_filename;
static Config * m_configInstance;
};
In case I'm not being clear, the getConfig() would look at m_configInstance. If it isn't a valid one, then it would create one (has access to the private constructor) and store it in m_configInstance so every subsequent call would access the same one.
So your main() would use setConfigFileName(), then any class would just have to call Config::getConfig() and then call the operations on it. A lot cleaner than a standard global variable.
Blast - in the time I spent writing this, other people have suggested the singleton design pattern too. Ah well - hope the additional explanation helps.

Have you looked at Boost's Program Options library?

What I have done for my configuration class is to create a singleton static class with a hashtable cache. My configuration file is designed to be read and written to for changing application settings.
Whenever a call is made to pull a setting, I perform a lookup on the hashtable, if it's not there, then I read the setting from the file, lock the hashtable, and put it into the hashtable. The hashtable very fast for lookups.

By mentioning the "static initialization order fiasco", I assume you need to have configuration items available to initialize some static objects. A singleton ConfigFile class will work, but you have to change the way you obtain the filename as the information is needed before main() is started. You'll need another singleton to provide the filename, or build the filename into the configuration class itself.

I agree with Chris, use a singleton. The nice thing about the singleton pattern is that it only initializes/gathers the data you need the first time you try to access it, from there on out it is available to everybody that is interested. If you are going to allow the configuration to change you will want to lock the writer.

I have used a technique similar to the singleton design pattern to configure global resources like this.
class Config
{
public:
Config(const string & filename) {
if (m_configInstance) {
throw AlreadyInitException;
}
// do main init
m_configInstance = this;
}
~Config() {
m_configInstance = 0;
}
static Config * getConfig() {
if (!m_configInstance) {
throw NoConfigException;
}
return m_configInstance;
}
private:
static Config * m_configInstance;
};
Config * Config * m_configInstance = 0;
The constructor tests that m_configInstance is not set, if it is it throws an exception. Then it finishes contruction and registers itself by setting m_configInstance to this.
The getConfig method returns the instance or throws and exception if it is not set.
The destructor sets the m_configInstance to 0 again.
To use the class construct it once in the start of main(). Then access it when required by the getConfig() method.
Now the lifetime of the Config object is cleanly controlled, unlike a singleton. And this has an added benefit for unit tests, each test or suite of tests can create there own Config object and they are all nicely cleaned up between tests.

Related

Constructors infinite cycle in cpp

I have a Logger singleton class that its purpose is to print messages to log file / screen.
This Logger has some configurations that he wants to read from configuration file. Here is the constructor of Logger:
Logger::Logger(const std::string& confFilePath) {
m_logConf = new LogConfig(confFilePath);
...
}
Class LogConfig uses Configuration Object that knows how to parse a configuration file. Here is the class Ctor:
LogConfig::LogConfig(const std::string& confFilePath) {
m_config = new Configuration(confFilePath);
...
m_config->ParseConfFile();
}
The problem is that in ParseConfFile method - Configuration object may want to write to the log and use Logger singleton class. But, when it tries to do it - he will enter again to Logger constructor, and then to LogConfig Ctor and there is an infinite cycle.
I don't want to forbid Configuration class to write to the log (LogConfig is not the only class that uses it).
How can I solve this cycle problem?
Initialize the logger with a bare minimum so you don't need the configuration at all.
Then when you have the configuration replace the logger.
If the config reader needs to log anything it will go to the bare minimum logger so you should at least dump it to stderr.
Also if you are in a multi-threaded environment make sure you use a shared_ptr and do an atomic swap to replace it with the propper one (in case some other module is logging when you need to swap).
Since Logger is a singleton, supposedly all classes (including Configuration) access it through a static method(say getInctance()), and Logger's constructor is private. The right approach would be to simplify Logger's construction to bare minimum and move the setup/configuration logic from the constructor to getInstance().
Something like:
static Logger* Logger::getInstance() {
if (m_logger == nullptr) {
m_logger = new Logger(); // remove configuration path passing from the constructor
m_logger->setConfigPath(const std::string& confFilePath); // ok trying to write to Logger, at least from the perspective of not being stuck in construction loop
}
return m_logger;
}
Although the behavior in this situation still needs to be defined, since the Logger is not fully initialized when Configuration tries wryting to it.
One approach would be to throw an exception or write an error message to the standard output when someone wants to use Logger before it's fully initialized.

Using inheritance to add functionality

I'm using an abstract base class to add logging functionality to all of my classes. It looks like this:
class AbstractLog
{
public:
virtual ~AbstractLog() = 0;
protected:
void LogException(const std::string &);
private:
SingletonLog *m_log; // defined elsewhere - is a singleton object
};
The LogException() method writes the text to the log file defined in the SingletonLog object, and then throws an exception.
I then use this as my base class for all subsequent classes (there can be hundreds/thousands of these over hundreds of libraries/DLLs).
This allows me to call LogException() wherever I would normally throw an exception.
My question is whether or not this is good design/practice.
P.S.: I'm using inheritance simply to add functionality to all of my classes, not to implement any sort of polymorphism. On top of this, the concept of all of my classes having an is-a relationship with the AbstractLog class is arguable (each class is-a loggable object? Well, yes I suppose they are, but only because I've made them so).
What you suggesting will work, I think better is to create log class ( inheriting from this interface ) and use it as in a way composition ( using interface ) than inheritance - composition is weaker connection between your logic class and log class. The best practice is the less class does the better. Additional benefit is that you will be able to extend log functionality any time you want without modification of business logic.
About this singleton, maybe proxy pattern is better ?
Hope, I helped :)
This seems like overkill to me. And inheritance is supposed to express the is a relationship. So, in your case, you are kind of saying that every class in you project is a logger. But really you only want one logger hence the singleton.
It seems to me that the singleton gives you the opportunity to avoid both inheriting from your logger class and storing a logger class as a member. You can simply grab the singleton each time you need it.
class Logger
{
public:
void error(const std::string& msg);
void warning(const std::string& msg);
void exception(const std::string& msg);
// singleton access
static Logger& log()
{
// singleton
static Logger logger;
return logger;
}
};
class Unrelated
{
public:
void func()
{
// grab the singleton
Logger::log().exception("Something exceptional happened");
}
};
I suppose I am saying it seems less obtrusive to grab your singleton through a single static method of your logger than by having every class in the project inherit from the logger class.
I'm not sure you gain anything by having a free function to log the exception. If you have a LogException free function then presumbaly you'd also need free functions for LogError and LogWarning (to replicate Galik's functionality) and the Logger object would either be a non-local static object defined at file scope and instantiated at startup or you would need another free function (similar to the Logger method and called from all the other logging functions) in which the Logger object would be a local static object instantiated the first time the method is called. For me the Logger object captures all this neatly in one go.
Another point to consider is performance - if you're going to have a large number of objects all using a static logging object then the object could potentially struggle with a high rate of writing to the log file and your main business logic could get blocked on a file write. It might be worth considering adding the errors and warning messages to a queue inside the Logger object and then having a separate worker thread going through the queue and do the actual file writes. You would then need thread protection locks around the writing to and reading from this internal queue.
Also if you are using a static logging object then you need to be sure that the entire application including the DLLs is single threaded otherwise you could get multiple threads writing to the same file simultaneously and you'd need to put thread protection locks into the Logger even if you didn't use an internal queue.
Except from the friend relationship, inheritance is the strongest coupling that can be expressed in C++.
Given the principle of louse coupling, high cohesion, I think it is better to use a looser type of coupling if you just want to add functionality to a class.
As the logger is a singleton making LogException a free function is the simplest way to achieve the same goal without having the strong coupling you get with inheritance.
"...use this as my base class for all subsequent classes..." -- "...question is whether or not this is good design / practice."
No it is not.
One thing you usually want to avoid is multiple inheritance issues. If every class in your application is derived from some utility class, and then another utility class, and then another utility class... you get the idea.
Besides, you're expressing the wrong thing -- very few of your classes will actually be specialized loggers, right? (That is what inheritance implies -- is a.)
And since you mentioned DLLs... you are aware of the issues implied in C++ DLLs, namely the fragility of the ABI? You are basically forcing clients to use the very same compiler and -version.
And if your architecture results in (literally) hundreds of libraries, there's something very wrong anyways.

C++: duplicated static member?

I have a class which needs to be a singleton. It implemented using a static member pointer:
class MySinglton
{
public:
static MySinglton& instance() { ... }
private:
static MySinglton* m_inst;
};
This class is compiled into a .lib which is used in multiple dlls in the same application. The problem is that each dll sees a different m_inst. since it is compiled and linked separatly.
What is simple way to solve this problem?
Separating the .lib to its own dll is not an option. it must be a .lib.
One way solving the problem is that creating a shared memory, and creating the object in the shared memory. The two modules still have two copies of the pointers, but they point to the same location i.e. same instance of an object.
A solution could be transferring the instantiation to the application, and the DLLs will get reference to it during initialization.
It may not be as elegant as you'd like, but it would do it.
Need to know what's the REAL problem behind your question.
The answer may not be in the form you expect it. ;)
I don't know if you consider this simple, but you'll need to allocate a "master instance" (on the heap, say) and then let all your MySingleton instances refer to the "master instance".
C++ has no built-in mechanism for sharing variables in the way you seem to want. The only solution is to pass the single instance as a function parameter, using a pointer or reference.
I would use the shared memory mechanism provided by your os, MapViewOfFile or shmem. This might go:
class MySinglton
{
public:
static MySinglton& instance() {
static MySinglton* m_inst = get_shared();
return *m_inst;
}
private:
static MySinglton * get_shared()
{
//1. Try to open shared memory, handle = OpenFileMapping.
//2. If successful, return MapViewOfFile(handle).
//3. Else, allocate enough space using CreateFileMapping, sizeof(MySingleton).
//4. Initialise MapViewOfFile(handle), return MapViewOfFile(handle).
}
void Initialise()
{
// Stuff you would normally do in operator new here.
}
};
Not sure if it's the best way to do it... but I'll do it like that :
Build your singleton in a DLL itself, then add external methods:
- to init it
- to retrieve it.
There is no simple solution to your problem.
Questions: If there is no solution shoosh what are you going to do? Abandon the project? Or re-structure it so the 'must be a .lib' constraint is removed? If this problem concerns a commercial project what are you going to say to the project manager, stakeholders, etc?

OO Programming Question: Global Object

I have probably a quite simple problem but I did not find a proper design decision yet.
Basically, I have 4 different classes and each of those classes has more than 10 methods.
Each of those classes should make use of the same TCP Socket; this object keeps a socket open to the server throughout program execution. My idea was to have the TCP obejct declared as "global" so that all other classes can use it:
classTCP TCPSocket;
class classA
{
private:
public:
classA();
...
};
class classB
{
private:
public:
classB();
...
};
Unfortunately, when declaring it like this my C++ compiler gives me an error message that some initialized data is written in the executable (???). So I am wondering if there is any other way I could declare this TCP object so that it is available for ALL the other classes and its methods?
Many thanks!
I'd suggest you keep the instance in your initialization code and pass it into each of the classes that needs it. That way, it's much easier to substitute a mock implementation for testing.
This sounds like a job for the Singleton design pattern.
The me sounds more for the right time to use Dependency Injection as i tend to avoid Singleton as much as i can (Singleton are just another way for accessing GLOBLAS, and its something to be avoided)
Singleton vs Dependency Injection has been already discussed on SO, check the "dependency injection" tag (sorry for not posting some links, but SO doens't allow me to post more than one link being a new user)
Wikipedia: Dependency Injection
As per your current code example, should be modified to allow injecting the Socket on the constructor of each Class:
class classA
{
private:
public:
classA(TCPSocket socket);
...
};
class classB
{
private:
public:
classB(TCPSocket socket);
...
};
Pass the socket into the constructor of each object. Then create a separate factory class which creates them and passes in the appropriate socket. All code uses the set of objects which are required to have the same socket should then create them via an instance of this factory object. This decouples the classes that should be using the single socket while still allowing the enforcement of the shared socket rule.
The best way to go about doing this is with a Singleton. Here is it's implementation in Java
Singleton Class:
public class SingletonTCPSocket {
private SingletonTCPSocket() {
// Private Constructor
}
private static class SingletonTCPSocketHolder {
private static final SingletonTCPSocket INSTANCE = new SingletonTCPSocket ();
}
public static SingletonTCPSocket getInstance() {
return SingletonTCPSocket.INSTANCE;
}
// Your Socket Specific Code Here
private TCPSocket mySocket;
public void OpenSocket();
}
The class that needs the socket:
public class ClassA {
public ClassA {
SingletonTCPSocket.getInstance().OpenSocket();
}
}
When you have an object which is unique in your program and used in a lot of places, you have several options:
pass a reference to the object everywhere
use a global more or less well hidden (singleton, mono-state, ...)
Each approach have its drawbacks. They are quite well commented and some have very strong opinions on those issues (do a search for "singleton anti-pattern"). I'll just give some of those, and not try to be complete.
passing a reference along is tedious and clutter the code; so you end up by keeping these references in some long lived object as well to reduce the number of parameters. When the time comes where the "unique" object is no more unique, you are ready? No: you have several paths to the unique object and you'll see that they now refer to different objects, and that they are used inconsistently. Debugging this can be a nightmare worse than modifying the code from a global approach to a passed along approach, and worse had not be planned in the schedules as the code was ready.
global like approach problem are even more well known. They introduce hidden dependencies (so reusing components is more difficult), unexpected side-effect (getting the right behaviour is more difficult, fixing a bug somewhere triggers a bug in another components), testing is more complicated, ...
In your case, having a socket is not something intrinsically unique. The possibility of having to use another one in your program or to reuse the components somewhere were that socket is no more unique seems quite high. I'd not go for a global approach but a parametrized one. Note that if your socket is intrinsically unique -- says it is for over the network logging -- you'd better encapsulate it in a object designed for that purpose. Logging for instance. And then it could make sense to use a global like feature.
As everyone has mentioned, globals are bad etc.
But to actually address the compile error that you have, I'm pretty sure it's because you're defining the global in a header file, which is being included in multiple files. What you want is this:
something.h
extern classTCP TCPSocket; //global is DECLARED here
class classA
{
private:
public:
classA();
...
};
something.cpp
classTCP TCPSocket; //global is DEFINED here

What's the proper "C++ way" to do global variables?

I have a main application class, which contains a logger, plus some general app configurations, etc.
Now I will display a lot of GUI windows and so on (that will use the logger and configs), and I don't want to pass the logger and configurations to every single constructor.
I have seen some variants, like declaring the main class extern everywhere, but that doesn't feel very object oriented. What is the "standard" C++ way to make elements in the main class accessible to all (or most) other classes?
Use the singleton design pattern.
Basically you return a static instance of an object and use that for all of your work.
Please see this link about how to use a singleton and also this stackoverflow link about when you should not use it
Warning: The singleton pattern involves promoting global state. Global state is bad for many reasons.
For example: unit testing.
It is not so bad idea to pass the logger and config to all the constructors if your logger and config is abstract enough.
Singleton can be a problem in the future. But it seams like a right choice in the project begin. Your choice. If your project is small enough - go with singleton. If not - dependency injection.
Why not use the system that's already in place? That is, redirect std::clog to output to a file and write to std::clog.
std::fstream *f = new std::fstream("./my_logfile.log")
std::clog.rdbuf(f->rdbuf());
std::clog << "Line of log information" << std::endl;
I'd agree with some kind of singleton approach. You definitely don't want to pass logger objects around all over the place. That will get very boring very quickly, and IMHO is a worse design than just having a plain global object.
A good test of whether you've got a good solution is the steps required to get the logging working in a function that needs it.
If you have to do much more than
#include "Logger.h"
...
void SomeFunction()
{
...
LOGERROR << "SomeFunction is broken";
...
}
...
then you are wasting effort.
Logging falls under the realm of 'separation of concern' as in aspect orient programming
Generally logging is not a function or concern of an object (for example, it does not change the state of the object; it is merely a mechanism for observing/recording the state, and the output is essentially disposable in most contexts)
It is an ephemeral and often optional side function that does not contribute to the operation of a class.
An object's method may perform logging, but the logging may be done there because it is a convenient place to do it or that point in the code execution stream is where one desires the state to be recorded.
Because C++ does not provide facilities for defining aspects, I tend to simply keep essentially external ephemeral objects like loggers global and wrap them in a namespace to sort of contain them. Namespaces are not intended for containment so this is kind of ugly, but for for lack of anything else it is convenient and is far less ugly and inconvienent than passing loggers in formal parameters or referencing them in all the objects you want to log. This also makes it easier to remove the logger if at some point I decide I no longer need the logger (I.e. if it was only used for debugging).
Don't know if this is helpful in your situation or not, but in MFC, there was/is an application class.
I use to throw things like this into that class.
I assume you are not using MFC, but if you have an application class or something similar, this might be helpful.
Why not use log4cxx?
Such problems are solved long ago and widely used by many.
Unless you're building some very special logging system of your own... In such case, I'd use Factory pattern which would create loggers for anyone interested (or giving away existing instance if it's singleton). Other classes would use factory to obtain the logger. Passing loggers in constructor parameters is a bad idea, because it couples your class with logger.
Why has no one thought of heritage and polymorphism? You could also use an abstract factory with that singleton ;)
Simply pass your main class into the constructor of the other classes that you want to have access to "everything"
Then you can provide access to the logger etc. via member properties.
(Forgive my C++ syntax, this is just a made-up language called "C++ confused by VB")
e.g.
Class App {
Private m_logger;
Private m_config;
Public logger() {
return m_logger;
}
Public config() {
return m_config
}
}
Class Window1 {
New( anApp ) {
}
....
}
I guess Service Locator will do. That you'll have to either pass around in constructors, or have a globally accessible static member function in some well-known location. The former option is much more preferable.
I would avoid the singleton pattern.
Too many problems when it comes to testing and all that (see What is so bad about singletons?)
Personally I would pass the logger etc into the constructor. Alternatively you can use a factory to create/pass a reference to the resource.