In Meyer's singleton pattern, we saw how we can use meyer's implementation approach of singleton design pattern to destroy the singleton object efficiently. It seems perfect at the first glance. However, it has certain problem called Dead reference problem. Let us try to understand it with the help of an example :
Let us say there are two static objects of class A and B and we have a singleton design pattern class called log that errors out if there is some error in creation or deletion of A or B. As we had studied in the last post that singleton object is created in Instance() function when it is called first time. A and B calls Instance() function of log while initialization and destruction if there occurs some error. Let us say object of A got created successfully but while constructing object of B there comes some error and it calls Instance() function of log Hence singleton object got created and possibly whole application exits out after this. Since compiler destroys local static object in the reverse order of their creation Hence log will be destroyed before object of A and let us say there occurs some error in destruction of A Instance() function return an Invalid object and program can behave unexpected. This is called dead reference problem.
Before thinking its solution we should understand what the real problem is. Problem is that we do not know the order of creation of object of A,B and log. A and B should follow the C++ rule(last object created first) but log should be exempted from this rule. log should destroyed after destruction of A and B so that it can catch all errors thrown by creation or destroy of A and B.
We have no way yet to control lifetime of objects (at least not in this post) but we can atleast detect dead reference problem that can be done by keeping a static bool variable called deleted_ inside singleton class which is initialized to false and set to true in its destructor.
class Singelton {
static bool deleted_;
public :
Singleton& Instance() {
if( !deleted ) {
static singleton obj;
return obj;
} else {
throw std::runtime_error("dead reference detected") ;
}
}
~Singeton() {
inst_ = 0;
deleted_ = true;
}
};
bool Singleton::deleted_ = false;
If some object tries to access singleton after its destruction, It will throw an error.