C++

C++ : Singleton Design Pattern

  • Singleton is a design pattern that is used to make sure that only one object of a class (type) exist.
  • Singleton provides just 1 way of accessing the only object that exist.

In the below example we have a random number generator that uses a Singleton design pattern.

Writing Singleton
- Making the constructor private ensures that an object of the singleton is not created.
- The usage of the copy constructor has been disabled by appending = delete to the copy constructor declaration.
- A single static instance of the class (Random) exist that can only be accessed using a static method.
- The usage of the assignment operator has been disabled by appending = delete to the assignment operator.

C++ program shows a way to implement a Singleton class (design pattern)

#include<iostream>
#include<cstdlib>

class Random {

    private:
    // Make the default constructor private.
    Random () {}

    public:
    // Delete the copy constructor function.
    Random (const Random&) = delete;

    // Delete the overloading of assignment operator
    Random& operator = (const Random&) = delete;

    static Random& Get() {
        static Random inst;
        return inst;
    }
     
    // Seed the random number generator.
    void Seed () {
        srand(time(NULL));
    }

    int GenInt () {
        return rand() % 100;
    }   
};

int main() {
    // Below call invokes a copy constructor. 
    // Hence delete the copy constructor function in the class.
    // Random inst = Random::Get();
    Random :: Get().Seed();

    int i = 1;
    std :: cout << "Generating 10 random integers..." << std :: endl;
    while (i<=10) {
        std :: cout << Random::Get().GenInt() << " ";
        i++;
    }   
    return 0;
}

Output

Generating 10 random integers...
7 45 61 85 8 3 5 44 2 75

Implementing Singleton design pattern as a template for any given class.

#include<iostream>
#include<cstdlib>

template<class T>
class Singleton {

    private:
    // Make the default constructor private.
    Singleton () {}

    public:
    // Delete the copy constructor function.
    Singleton (const T&) = delete;

    // Delete the overloading of assignment operator
    T& operator = (const T&) = delete;

    static T& Get() {
        static T inst;
        return inst;
    }
};

class Foo {
    private:
    int foo_var;
    public:
    Foo() { foo_var = 10; }
    Foo (const Foo&) = delete;
    Foo& operator = (const Foo&) = delete;
    void Disp() {
        std :: cout << "foo_var set to : " << foo_var << std::endl;
        foo_var++;
    }
};

class Bar {
    private:
    char bar_var;
    public:
    Bar() { bar_var = 'a'; }
    Bar (const Bar&) = delete;
    Bar& operator = (const Bar&) = delete;
    void Disp() {
        std :: cout << "bar_var set to : " << bar_var << std::endl;
        bar_var++;
    }
};

int main() {

    // Below assignment fails because the copy contructor of Foo is deleted.
    // Foo f1 = Singleton<Foo> :: Get();
 
    Singleton<Foo> :: Get().Disp();
    Singleton<Foo> :: Get().Disp();
    Singleton<Foo> :: Get().Disp();

    Singleton<Bar> :: Get().Disp();
    Singleton<Bar> :: Get().Disp();
    Singleton<Bar> :: Get().Disp();

    return 0;
}

Output

foo_var set to : 10
foo_var set to : 11
foo_var set to : 12
bar_var set to : a
bar_var set to : b
bar_var set to : c


Copyright (c) 2019-2022, Algotree.org.
All rights reserved.