Creating a Singleton Class

Problem

You have a class that must only ever be instantiated once, and you need to provide a way for clients to access that class in such a way that the same, single object is returned each time. This is commonly referred to as a singleton pattern, or a singleton class.

Solution

Create a static member that is a pointer to the current class, restrict the use of constructors to create the class by making them private, and provide a public static member function that clients can use to access the single, static instance. Example 8-9 demonstrates how to do this.

Example 8-9. Creating a singleton class

#include 

using namespace std;

class Singleton {
public:
 // This is how clients can access the single instance
 static Singleton* getInstance( );

 void setValue(int val) {value_ = val;}
 int getValue( ) {return(value_);}

protected:
 int value_;

private:
 static Singleton* inst_; // The one, single instance
 Singleton( ) : value_(0) {} // private constructor
 Singleton(const Singleton&);
 Singleton& operator=(const Singleton&);
};

// Define the static Singleton pointer
Singleton* Singleton::inst_ = NULL;

Singleton* Singleton::getInstance( ) {
 if (inst_ == NULL) {
 inst_ = new Singleton( );
 }
 return(inst_);
}

int main( ) {

 Singleton* p1 = Singleton::getInstance( );

 p1->setValue(10);
 
 Singleton* p2 = Singleton::getInstance( );

 cout << "Value = " << p2->getValue( ) << '
';
}

 

Discussion

There are many situations where you want at most one instance of a classthis is why Singleton is a design pattern. With a few simple steps, it's easy to implement a singleton class in C++.

When you decide that you only want one instance of something, the static keyword should come to mind. As I described in Recipe 8.5, a static member variable is one such that there is at most one instance of it in memory. Use a static member variable to keep track of the one object of your singleton class, as I did in Example 8-9:

private:
 static Singleton* inst_;

Keep it private to keep client code from knowing about it. Be sure to initialize it to NULL with a static variable definition in an implementation file:

Singleton* Singleton::inst_ = NULL;

To keep clients from instantiating this class, make the constructors private, especially the default constructor.

private:
 Singleton( ) {}

This way, if anyone tries to create a new singleton class on the heap or the stack, they'll get a friendly compiler error.

Now that you've created a static variable to keep track of the one Singleton object, and you've prohibited creation of Singleton objects by restricting their constructors, all that's left is to provide a way for clients to access the one instance of the Singleton object. Do this with a static member function:

Singleton* Singleton::getInstance( ) {
 if (inst_ == NULL) {
 inst_ = new Singleton( );
 }
 return(inst_);
}

You can see how this works. If the static Singleton pointer is NULL, create the object. If it has already been created, just return its address. Clients can access the one instance of Singleton by calling this static member:

Singleton* p1 = Singleton::getInstance( );

And if you don't want clients to deal with pointers, you can return a reference, too:

Singleton& Singleton::getInstance( ) {
 if (inst_ == NULL) {
 inst_ = new Singleton( );
 }
 return(*inst_);
}

The point here is that in both cases you have prevented clients from creating instances of a Singleton object and provided a single interface through which they can gain access.

See Also

Recipe 8.3

Building C++ Applications

Code Organization

Numbers

Strings and Text

Dates and Times

Managing Data with Containers

Algorithms

Classes

Exceptions and Safety

Streams and Files

Science and Mathematics

Multithreading

Internationalization

XML

Miscellaneous

Index



C++ Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2006
Pages: 241

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net