Is there an issue with this singleton implementation? - c++

I've typically gotten used to implementing a singleton pattern in this manner because it's so easy:
class MyClass
{
public:
MyClass* GetInstance()
{
static MyClass instance;
return &instance;
}
private:
//Disallow copy construction, copy assignment, and external
//default construction.
};
This seems significantly easier than creating a static instance pointer, initializing it in the source file, and using dynamic memory allocation in the instance function with guards.
Is there a downside that I'm not seeing? It looks thread-safe to me because I would think the first thread to get to the first line would cause the instantiation - and it seems nice and concise. I figure there has to be a problem I'm not seeing since this is not common though - I'd like to get some feedback before I keep using it

This is not an inherent threadsafe solution: while constructing the instance, another thread can preempt and try to get the instance, resulting in either a double instance or in using an unconstructed instance.
This is handled by several compilers by adding a guard (in gcc, I think there is a flag to disable this) because there is no way to guard this with a userdefined mutex.

The downside is that you have no control over exactly when the object is destroyed. This will be a problem if other static objects try to access it from their destructors.
A C++11 compliant compiler must implement this in a thread-safe way; however, older compilers might not. If you're in doubt, and you don't especially want lazy initialisation, you could force the object to be created by calling the accessor before starting any threads.

There are two issues in the interface:
You should return a reference
You should make either the destructor or the delete operator private
Also, there is a slight risk of attempting to using this class after it's been destructed.
Regarding your multi-threading concerns (and initialization I guess): it's fine in C++11 and have been fine for a long time on good C++ compilers anyway.

Aside from in a multi-threaded scenario - no. Well - let me qualify this, construction is lazy (so the first call may have a hit) and destruction - well, there is no guarantee (aside from it will be - at some point)

Generally speaking, qualifier static for local variable in a method doesn't guarantee that the variable is created only once. If the method is called by different threads, it could be created once for each thread so many times, as many threads called it. It should be not confused with static member of the class, which is created once before program is started. Thread safety of local static variables depends on particular realization of c++. Useful link : Are function static variables thread-safe in GCC?
Hope it helps.

Related

Is it OK for a class constructor to block forever?

Let's say I have an object that provides some sort of functionality in an infinite loop.
Is is acceptable to just put the infinite loop in the constructor?
Example:
class Server {
public:
Server() {
for(;;) {
//...
}
}
};
Or is there an inherent initialization problem in C++ if the constructor never completes?
(The idea is that to run a server you just say Server server;, possibly in a thread somewhere...)
It's not wrong per standard, it's just a bad design.
Constructors don't usually block. Their purpose is to take a raw chunk of memory, and transform it into a valid C++ object. Destructors do the opposite: they take valid C++ objects and turn them back into raw chunks of memory.
If your constructor blocks forever (emphasis on forever), it does something different than just turn a chunk of memory into an object.
It's ok to block for a short time (a mutex is a perfect example of it), if this serves the construction of the object.
In your case, it looks like your constructor is accepting and serving clients. This is not turning memory into objects.
I suggest you split the constructor into a "real" constructor that builds a server object and another start method that serves clients (by starting an event loop).
ps: In some cases you have to execute the functionality/logic of the object separately from the constructor, for example if your class inherit from std::enable_shared_from_this.
It's allowed. But like any other infinite loop, it must have observable side effects, otherwise you get undefined behavior.
Calling the networking functions counts as "observable side effects", so you're safe. This rule only bans loops that either do literally nothing, or just shuffle data around without interacting with the outside world.
Its legal, but its a good idea to avoid it.
The main issue is that you should avoid surprising users. Its unusual to have a constructor that never returns because it isn't logical. Why would you construct something you can never use? As such, while the pattern may work, it is unlikely to be an expected behavior.
A secondary issue is that it limits how your Server class can be used. The construction and destruction processes of C++ are fundamental to the language, so hijacking them can be tricky. For example, one might want to have a Server that is the member of a class, but now that overarching class' constructor will block... even if that isn't intuitive. It also makes it very difficult to put these objects into containers, as this can involve allocating many objects.
The closest I can think of to what you are doing is that of std::thread. Thread does not block forever, but it does have a constructor that does a surprisingly large amount of work. But if you look at std::thread, you realize that when it comes to multithreading, being surprised is the norm, so people have less trouble with such choices. (I am not personally aware of the reasons for starting the thread upon construction, but there's so many corner cases in multithreading that I would not be surprised if it resolves some of them)
A user might expect to set up your Server object in the main thread. Then call the server.endless_loop() function within a worker thread.
In an actual server, the process of acquiring a port requires escalated privileges which can then be dropped. Or perhaps you have an object that needs to load settings. Those sort of tasks could take place in the main thread before the long term looping takes place elsewhere.
Personally, I'd prefer your object had a "poll" function that was fast and non blocking. You could then have a loop function that called poll and sleep in an endless loop. You might even have an atomic variable that you can set to exit the loop from a different thread. Another feature would be to launch an internal thread within the Server object.
As others have pointed out, there's nothing "wrong" with this as far as C++ semantics are concerned, but it's poor design. The point of a constructor is to construct an object, so if that task never completes then it will be surprising to users.
Others have made suggestions regarding splitting the construction & run steps into constructor and method, which makes sense if you have other things you might want to do with the Server besides run it, or if you actually might want to construct it, do other stuff, and then run it.
But if you expect the caller will always just do Server server; server.run(), then maybe you don't even need a class -- it could just be a stand-alone function run_server(). If you don't have state to encapsulate and pass around in the first place, then you don't necessarily need objects. A stand-alone function can even be marked [[noreturn]] to make it clear both to the user and the compiler that the function never returns.
It's hard to say which makes more sense without knowing more about your use case. But in short: constructors construct objects -- if you're doing something else, don't use them for that.
In most cases, your code has no problem. Because of the following rule:
A class is considered a completely-defined object type ([basic.types]) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, noexcept-specifiers, and default member initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.
However, A restriction for your code is that you cannot use a glvalue that doesn't obtain from pointer this to access this object due to the behavior is unspecified. It's governed by this rule:
During the construction of an object, if the value of the object or any of its subobjects is accessed through a glvalue that is not obtained, directly or indirectly, from the constructor's this pointer, the value of the object or subobject thus obtained is unspecified.
Moreover, you cannot use the utility shared_ptr to manage such class objects. In general, place an infinitely loop into a constructor is not a good idea. Many restrictions will apply to the object when you use it.

C++: Is it bad to use global variables that are pointers to instantiations of single-instance-only classes?

In my program, I've got a bunch of classes that will only ever have one created instance for the duration of the program. They are created only once on initialization, and destroyed only once on closing.
These classes all tend to present really broad functionality that is used by many different parts of the program, and so having them as global externs is really clean and easy to understand, rather than encapsulating them in another class or passing around pointers.
The program is multi-threaded, and all of these classes contain their own mutex for access.
Are there any problems with this approach? If so, what are the recommended alternatives.
Use a singleton pattern as follows:
Foo& foo() { static Foo x; return x; }
This is completely thread-safe. See here: G++ 4.6 -std=gnu++0x: Static Local Variable Constructor Call Timing and Thread Safety
It is guaranteed by the current standard.
Furthermore this is superior to static initialized global variables because if you have multiple of the above they will be initialized lazily in the correct dependency order.
Foo& foo() { static Foo x; return x; }
Bar& bar() { static Bar x; return x; }
and in Bar::Bar there is a call to foo(), then the Foo singleton will be created before Bar.
If I had of used global variables:
// Foo.cpp
Foo foo;
// Bar.cpp
Bar bar;
No such ordering is guaranteed.
3.6.2 Initialization of non-local variables
...the initialization of a variable is indeterminately sequenced with respect to the initialization of a variable defined in a different translation unit....
You can use a Singleton, but be sure of thread safety. For a tutorial, take a look at SINGLETON PATTERN - 1. THREAD SAFETY
An example would be
static SomeSingleton* getInstance()
{
lock_mutex();
if(!pInstance_)
pInstance_ = new SomeSingleton();
unlock_mutex();
return pInstance_;
}
By using global variables in your classes you make them difficult to test. Their behaviour now depends on a global state, which makes it difficult to reason about them. One class depends on the global variable. Another class depends on it, too. Both can change the state of the global variable any time. In essence you have a created a mutual dependency between both classes. With every access to the global variable you are one step closer to one version of the dependency hell.
You have mentioned that you do not want to pass them around as pointers. Actually I would prefer that method. By explicitly passing a dependency (your global variables) to a method or constructor you tell the world about it. If you need to pass ten dependencies to your method, you might want to rethink your solution. It might be a lot of work, but helps to improve the architecture of your program.
You have written that your classes "tend to present really broad functionality". This might be an indicator that they should be broken down into smaller components, so that you only have to pass around the functionality that you actually need.
My advice is that
you should avoid using global variables, especially in the form of singletons
try to find out more about dependency injection to properly pass around your dependencies
watch video Don't look for things (Clean Code Talks, Misko Hevery)
c++ has big problems with order of calling global objects constructors
somebody calls it "global initialization fiasco"
It's not related with multithreading, but related with initialization
If your program has many global objects then it may cause some problems (of course there are some methods to solve that problem)
You can use pattern 'singleton' but I'm not sure will it be useful in your case

Should I use virtual 'Initialize()' functions to initialize an object of my class?

I'm currently having a discussion with my teacher about class design and we came to the point of Initialize() functions, which he heavily promotes. Example:
class Foo{
public:
Foo()
{ // acquire light-weight resources only / default initialize
}
virtual void Initialize()
{ // do allocation, acquire heavy-weight resources, load data from disk
}
// optionally provide a Destroy() function
// virtual void Destroy(){ /*...*/ }
};
Everything with optional parameters of course.
Now, he also puts emphasis on extendability and usage in class hierarchies (he's a game developer and his company sells a game engine), with the following arguments (taken verbatim, only translated):
Arguments against constructors:
can't be overridden by derived classes
can't call virtual functions
Arguments for Initialize() functions:
derived class can completely replace initialization code
derived class can do the base class initialization at any time during its own initialization
I have always been taught to do the real initialization directly in the constructor and to not provide such Initialize() functions. That said, I for sure don't have as much experience as he does when it comes to deploying a library / engine, so I thought I'd ask at good ol' SO.
So, what exactly are the arguments for and against such Initialize() functions? Does it depend on the environment where it should be used? If yes, please provide reasonings for library / engine developers or, if you can, even game developer in general.
Edit: I should have mentioned, that such classes will be used as member variables in other classes only, as anything else wouldn't make sense for them. Sorry.
For Initialize: exactly what your teacher says, but in well-designed code you'll probably never need it.
Against: non-standard, may defeat the purpose of a constructor if used spuriously. More importantly: client needs to remember to call Initialize. So, either instances will be in an inconsistent state upon construction, or they need lots of extra bookkeeping to prevent client code from calling anything else:
void Foo::im_a_method()
{
if (!fully_initialized)
throw Unitialized("Foo::im_a_method called before Initialize");
// do actual work
}
The only way to prevent this kind of code is to start using factory functions. So, if you use Initialize in every class, you'll need a factory for every hierarchy.
In other words: don't do this if it's not necessary; always check if the code can be redesigned in terms of standard constructs. And certainly don't add a public Destroy member, that's the destructor's task. Destructors can (and in inheritance situations, must) be virtual anyway.
I"m against 'double initialization' in C++ whatsoever.
Arguments against constructors:
can't be overridden by derived classes
can't call virtual functions
If you have to write such code, it means your design is wrong (e.g. MFC). Design your base class so all the necessary information that can be overridden is passed through the parameters of its constructor, so the derived class can override it like this:
Derived::Derived() : Base(GetSomeParameter())
{
}
This is a terrible, terrible idea. Ask yourself- what's the point of the constructor if you just have to call Initialize() later? If the derived class wants to override the base class, then don't derive.
When the constructor finishes, it should make sense to use the object. If it doesn't, you've done it wrong.
One argument for preferring initialization in the constructor: it makes it easier to ensure that every object has a valid state. Using two-phase initialization, there's a window where the object is ill-formed.
One argument against using the constructor is that the only way of signalling a problem is through throwing an exception; there's no ability to return anything from a constructor.
Another plus for a separate initialization function is that it makes it easier to support multiple constructors with different parameter lists.
As with everything this is really a design decision that should be made with the specific requirements of the problem at hand, rather than making a blanket generalization.
A voice of dissension is in order here.
You might be working in an environment where you have no choice but to separate construction and initialization. Welcome to my world. Don't tell me to find a different environment; I have no choice. The preferred embodiment of the products I create is not in my hands.
Tell me how to initialize some aspects of object B with respect to object C, other aspects with respect to object A; some aspects of object C with respect to object B, other aspects with respect to object A. The next time around the situation may well be reversed. I won't even get into how to initialize object A. The apparently circular initialization dependencies can be resolved, but not by the constructors.
Similar concerns goes for destruction versus shutdown. The object may need to live past shutdown, it may need to be reused for Monte Carlo purposes, and it might need to be restarted from a checkpoint dumped three months ago. Putting all of the deallocation code directly in the destructor is a very bad idea because it leaks.
Forget about the Initialize() function - that is the job of the constructor.
When an object is created, if the construction passed successfully (no exception thrown), the object should be fully initialized.
While I agree with the downsides of doing initialization exclusively in the constructor, I do think that those are actually signs of bad design.
A deriving class should not need to override base class initialization behaviour entirely. This is a design flaw which should be cured, rather than introducing Initialize()-functions as a workaround.
Not calling Initialize may be easy to do accidentally and won't give you a properly constructed object. It also doesn't follow the RAII principle since there are separate steps in constructing/destructing the object: What happens if Initialize fails (how do you deal with the invalid object)?
By forcing default initialization you may end up doing more work than doing initialization in the constructor proper.
Ignoring the RAII implications, which others have adequately covered, a virtual initialization method greatly complicates your design. You can't have any private data, because for the ability to override the initialization routine to be at all useful, the derived object needs access to it. So now the class's invariants are required to be maintained not only by the class, but by every class that inherits from it. Avoiding that sort of burden is part of the point behind inheritance in the first place, and the reason constructors work the way they do with regard to subobject creation.
Others have argued at length against the use of Initialize, I myself see one use: laziness.
For example:
File file("/tmp/xxx");
foo(file);
Now, if foo never uses file (after all), then it's completely unnecessary to try and read it (and would indeed be a waste of resources).
In this situation, I support Lazy Initialization, however it should not rely on the client calling the function, but rather each member function should check if it is necessary to initialize or not. In this example name() does not require it, but encoding() does.
Only use initialize function if you don't have the data available at point of creation.
For example, you're dynamically building a model of data, and the data that determines the object hierarchy must be consumed before the data that describes object parameters.
If you use it, then you should make the constructor private and use factory methods instead that call the initialize() method for you. For example:
class MyClass
{
public:
static std::unique_ptr<MyClass> Create()
{
std::unique_ptr<MyClass> result(new MyClass);
result->initialize();
return result;
}
private:
MyClass();
void initialize();
};
That said, initializer methods are not very elegant, but they can be useful for the exact reasons your teacher said. I would not consider them 'wrong' per se. If your design is good then you probably will never need them. However, real-life code sometimes forces you to make compromises.
Some members simply must have values at construction (e.g. references, const values, objects designed for RAII without default constructors)... they can't be constructed in the initialise() function, and some can't be reassigned then.
So, in general it's not a choice of constructor vs. initialise(), it's a question of whether you'll end up having code split between the two.
Of bases and members that could be initialised later, for the derived class to do it implies they're not private; if you go so far as to make bases/members non-private for the sake of delaying initialisaton you break encapsulation - one of the core principles of OOP. Breaking encapsulation prevents base class developer(s) from reasoning about the invariants the class should protect; they can't develop their code without risking breaking derived classes - which they might not have visibility into.
Other times it's possible but sometimes inefficient if you must default construct a base or member with a value you'll never use, then assign it a different value soon after. The optimiser may help - particularly if both functions are inlined and called in quick succession - but may not.
[constructors] can't be overridden by derived classes
...so you can actually rely on them doing what the base class needs...
[constructors] can't call virtual functions
The CRTP allows derived classes to inject functionality - that's typically a better option than a separate initialise() routine, being faster.
Arguments for Initialize() functions:
derived class can completely replace initialization code
I'd say that's an argument against, as above.
derived class can do the base class initialization at any time during its own initialization
That's flexible but risky - if the base class isn't initialised the derived class could easily end up (due to oversight during the evolution of the code) calling something that relies on that base being initialised and consequently fails at run time.
More generally, there's the question of reliable invocation, usage and error handling. With initialise, client code has to remember to call it with failures evident at runtime not compile time. Issues may be reported using return types instead of exceptions or state, which can sometimes be better.
If initialise() needs to be called to set say a pointer to nullptr or a value safe for the destructor to delete, but some other data member or code throws first, all hell breaks loose.
initialise() also forces the entire class to be non-const in the client code, even if the client just wants to create an initial state and ensure it won't be further modified - basically you've thrown const-correctness out the window.
Code doing things like p_x = new X(values, for, initialisation);, f(X(values, for initialisation), v.push_back(X(values, for initialisation)) won't be possible - forcing verbose and clumsy alternatives.
If a destroy() function is also used, many of the above problems are exacerbated.

What is wrong with using a static member object with a class?

I have heard that using static member objects is not a very good practice.
Say for example, I have this code:
class Foo {
...
static MyString str;
};
I define and initialize this variable in the implementation file of this class as:
MyString Foo::str = "Some String"; // This is fine as my string API handles this.
When I run this code, I get a warning:
warning:'Foo::str' requires global construction.
I have quite much of such members in my class, what is the best way to handle this.
Thanks,
Most of the arguments against them are the same as for global variables:
Initialization order between different compilation units is undefined.
Initialization order inside one compilation unit may affect the behavior — thus non trivial ordering may be required.
If a constructor throws an exception you can't catch it, your program is terminated.
APPENDED: To handle this properly you must either make sure that above points don't apply to your code and ignore the warning, or redesign your program: Do you really need them static? Why not use const char* Foo::str = "Some String";?
The biggest reason for concern with this example is that constructing the static member object happens before main() and destruction happens after main() (or when you call exit()). So far, that's a good thing. But when you have multiple objects like this in your program, you risk a bug where code attempts to use an object that has not yet been constructed or has already been destroyed.
The C++ FAQ Lite has some helpful discussion on this topic, including a workaround/solution. Recommended reading is questions 10.14 through 10.18. 10.17 is most directly applicable to your example.
Using a static member, you are not guaranteeing thread safety, imagine two threads trying to access the static member - now what would be the value of that member - was it the one from thread x or thread y, this also induces another side-effect, race conditions, where one thread modifies the static member before the other thread completes... in other words, using a static member can be hazardous...
As an example, it is required to know the number of instances of a class. This would require a class static member to track the count of instances.
There is nothing wrong in having a static member of a class if the problem solution requires such a design. It's just that the nitty gritties have to be taken care as mentioned in other posts.

C++ Threadsafe Singleton (NOT FOR INIT)

So I want to access a singleton class from multiple threads. Conceptually I'd think that calling non-const methods on this singleton instance would be not thread-safe. I've been looking online and no one seems to address this possible issue. Is there an actual problem with this, is the only issue with Singleton's thread-safety, the initialization of the instance variable?
A singleton instance has the same thread safety issues as any other instance, so calls to its methods or access to its members should be synchronized.
The initialization of the singleton itself is another issue...in gcc static initialization is threadsafe, but probably not so much on other platforms.
Also take a look at this paper addressing some threading singleton issues by Andrei Alexandrescu. His Modern C++ Design book also addresses singleton issues.
You are correct, calling a non-const methods or methods that depend on instance data that could be modified by other threads must be syncronized.
Apart from the thread-safety issue with the initialization of instance variable, the singleton objects should be treated as any other normal objects with respect to thread-safety for the method calls.
ie, Any methods ( you need synchronization for const method as well, if we are trying to read the value of a variable, which will get updated in another method by another thread) of the singleton object accessed by multiple threads and involves in shared data read\write must be synchronized.