Creational

Singleton

Purpose

Allow one and only one instance of a given class to exist.

UML

Behavior

A client uses the class's interface to create and access the single instance.

Example

An application may use a "Session Manager"  module to log clients on/off and maintain their state throughout the application's lifetime. It makes since for an application to have only one Session Manager responsible for managing client access.

Usage

/* Singleton: A singleton class defines an operation that lets clients access the one and only one instance. A singleton is typically implemented by:
1. Restricting access to the constructor to ensure that the class cannot be  instantiated directly by clients (protected or private access specifiers cause compile-time error.) 
2. Adding a class operation, Instance(), that creates and returns the one instance of the class.
3. Accessing the singleton exclusively through the Instance() method.

In this example, an instance is used to ensure that there can be one and only one Session Manager.
 
Note: Review 'Beware the COM Singleton' in Effective COM by Don Box for advice with respect to applying the Singleton pattern with COM objects. */

class SessionManager
{
// Constructors
protected:
    /* protected access specifier was used to allow derived classes access to the 
    constructor, in case SessionManager was specialized */
    SessionManager(){}

// Data members/Helpers
private:
    static SessionManager* pInstance;

// Public interface
public:
    /* Creating a single instance is hidden in a class operation that guaranteed only
    one instance can exsit */
    static SessionManager* Instance()
    {
        if (0 == pInstance)
        {
            // Instance requested for first time. Create an instance of the object
            pInstance = new SessionManager;
        }
        return pInstance;
    }

    // Other public interface methods ...
    void LogOnClient( const std::string & strName)
    {
        std::cout << "Logging client " << strName << "into system..." << std::endl;

        // ...
    }
};

SessionManager* SessionManager::pInstance = 0;    // initialize static member variables

void Log( const std::string &);    // helper

int main(int argc, char* argv[])
{
    // Use the SessionManager singleton to log clients
    Log( "Name1" );
    Log( "Name2" );

    return 0;
}

// Logs a client using the unique instance of the Session Manager
void Log( const std::string & strName)
{
    // Retrieve one and only instance of SM
    SessionManager* pSM = SessionManager::Instance();

    // Invoke operations on the singleton
    pSM->LogOnClient( "yazan" );
}

Notes