Foreword

Recently I was working on a qt project I saw some of code that I have never seen before :

Sql.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef SQL_H
#define SQL_H

#include <QObject>
#include <QtSql>
#include <QList>
#include <QVariant>
#include <QDateTime>

class Sql : public QObject
{
Q_OBJECT

private:
static Sql *instance;
explicit Sql(QObject *parent = nullptr);
...

public:
static Sql *getInstance();
...
};

#endif // SQL_H

It is weird. Why the constuctor is private?

Sql.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "Sql.h"

...

// Prevent LNK2001
Sql *Sql::instance;

Sql *Sql::getInstance()
{
if(instance == nullptr)
{
instance = new Sql();
}
return instance;
}

...

So I wonder what is it, and I googled it and found out it is a practice of singleton pattern.

What is the Singleton Pattern?

It is used when you want to eliminate the option of instantiating more than one object.

Ensures that only one instance of a class is created, and provide a global point of access to it.

Singleton may be used when :

  • You need to access to a shared resource.
  • access to a shared resource will be requested from multiple, separate parts of your program.
  • Application needs only one instance of a class.
  • To have complete control over the instance creation.

Benefits

  • Controlled instantiation
  • Support both EAGER and LAZY initializations
  • Singletons can be converted into Mulititons (to support limited number of instances identified by keys)

Drawbacks

  • Often seens as ‘not-so-good’ design as it resembles global variables
  • Special handling is required if the Singleton object needs to be deleted
  • Singletons that maintain global state may cause issues

Examples for better understanding

Real World Examples

The Office of the President is considered as singleton since there can be only ONE President at any given time.

Software Examples

  • Logger classes - Only 1 Log
  • Window Manager
  • Printer Spooler

Structure

It is more clear.

SingleObject class provides a static method to get its static instance to outside world.
SingletonPatternDemo, our demo class will use SingleObject class to get a SingleObject object.

Implementation of getInstance()

An implementation of the singleton pattern must:

  • ensure that only one instance of the singleton class ever exists
  • provide global access to that instance

Typically, this is done by:

  • declaring all constructors of the class to be private
  • providing a static method that returns a reference to the instance

Lazy initialization

C++ Example

1
2
3
4
5
6
7
8
9
10
11
12
class Singleton {
private:
static Singleton* instance;
Singleton(){};
public:
static Singleton* getInstance(){
if(instance == NULL){
instance = new Singleton();
}
return instance;
}
};

Java Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Singleton {

private static Singleton firstInstance = null;

private Singleton(){}

public static Singleton getInstance(){

if(firstInstance == null){

firstInstance = new Singleton();

}

return firstInstance;
}
}

Reference

How does getInstance() work?
skyyen999-單例模式 Singleton (Java)
Singleton 模式
私有建構子 X 單身狗模式 - Private Constructor & Singleton Pattern
刘刘-单例模式(Singleton Pattern)
设计模式(一):单例模式(Singleton Pattern)
单例模式,这一篇差不多了 – Singleton is an angel but an evil!
Singleton in C++: Before and after
Singleton Design Pattern
Singleton pattern wiki