In Search of a Perfect Singleton

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.


“Design and programming are human activities; forget that and all is lost.” – Bjarne Stroustrup

CodeGuru Note: The code in this article is not thread safe. If it were, this perhaps would be an article about the perfect singleton.

Singleton Pattern

To begin with, a singleton is one of the most commonly used, as well as misused, design patterns. Why did I say misused? You will get the answer as you read on.

A singleton pattern is usually used to restrict the instances of a class; that is, the objects within the life cycle of the software program to one. But why do you need singletons? You use them:


  • To coordinate actions across the system

  • To improve upon the efficiency of the system

Care should be taken to identify the need and benefits of using a singleton. Often, one tends to use singletons to hide a global object.

How to Create a Singleton

Most of us know how to create a singleton. We have done it so many times by now. But, let me just do a quick recap.

The rule of thumb for singletons is that the direct instantiation through the constructor should be prevented. How do you instantiate or access the object? The solution is to provide a method that creates a new instance of the object if one does not exist. If an instance already exists, it simply returns a reference to that object.


C++
class Singleton {
Singleton() {
}
};

Remember that the default access in a C++ class is private. But, in the case of Java, the constructor inherits the access modifier of the class. If no access modifier is defined on the class, the default constructor has the default access implied by no access modifier. (Reference: Java Language Specification Second Edition 8.8.7 Default Constructor).

This means that, in the case of Java, care should be taken to explicitly make the access modifier of the constructor as private.


Java
package …;
public class Singleton {
private Singleton() {
}
};

Now that you have prevented the direct instantiation of the class, you need to provide a mechanism to access the object. Here is how to do this.


C++
class Singleton {
public:
static Singleton* getInstance() {
if (NULL == _instance) {
_instance = new Singleton();
}
return _instance;
}

private:
// default constructor
Singleton() {
}

// the single instance of the object
static Singleton* _instance;
};

Singleton* Singleton::_instance = NULL;


Java
public class Singleton {
public static Singleton getInstance() {
if (null == _instance) {
_instance = new Singleton();
}
return _instance;
}

// default constructor
private Singleton() {
}

// the single instance of the object
private static Singleton _instance;
};

You have ensured that only one instance exists and was given access to the same. Now, other required functionality can be added to the singleton class.

Is That All?

Are you done? No, not exactly. Remember I had said that this is an attempt to create a perfect singleton. So, what is wrong with the above? Have I missed something? Yes, I did. Although I have prevented the direct instantiation, an object can still be created. If you recollect the basics, all C++ classes, apart from having their default constructors, also have:


  • Copy constructor

  • Assignment operator

You need to declare these also as private to prevent access. You may ask why. You do so because:


  • A copy constructor will create a new object from the existing one. But, you are interested in limiting the instance to only one.

  • An assignment operator is not required for a Singleton; “_instance” is the only data member and has to point to the same object across all instances.


C++
class Singleton {
public:
static Singleton* getInstance() {
if (NULL == _instance) {
_instance = new Singleton();
}
return _instance;
}

private:
// default constructor
Singleton() {
}

// copy constructor
Singleton(const Singleton&) {
}

// assignment operator
Singleton& operator=(const Singleton&)

{
return *this;
}

// the single instance of the object
static Singleton* _instance;
};

Singleton* Singleton::_instance = NULL;

In the case of Java, you tend to forget about cloning just as you forget about copying the constructor. Although your singleton class does not define a clone method, you need to do so because the java.lang.Object class from which your singleton is inherited from defines the clone() method. To make your Singleton foolproof, you need to add a clone() method and prevent access to the same. Because you cannot make it private, you either can make it protected or override it and throw an exception or both.


Java
public class Singleton {
public static Singleton getInstance() {
if (null == _instance) {
_instance = new Singleton();
}
return _instance;
}

// default constructor
private Singleton() {
}

// clone
protected Object clone() throws

CloneNotSupportedException {
throw new CloneNotSupportedException();
}

// the single instance of the object private
static Singleton _instance;
};

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read