C++ singleton class template details

  • 2020-06-15 09:51:23
  • OfStack

Singleton class

describe

A class can only have at most one instance (instance) during the lifetime of the system, making the instance unique (instance refers to a pointer to an object), such as counting the number of people online

In the singleton class, it can be divided into lazy Chinese and hungry Chinese. The difference between them lies in the time of instance creation:

Lazy: When the code runs and the instance does not exist, it is created only when needed (single-threaded) Hanhungry type: refers to the code 1 running, the instance already exists, when needed, directly to call (applicable to multithreading)

usage

Set the access property of the constructor to private, One GetInstance() static member function is provided for users to access only 11 instances. Defines a static member pointer for the user to retrieve Overload (=) assignment operator and copy constructor and set to private to avoid copying between objects.

A preliminary study of singletons - Lazy Han:


#include <iostream>
using namespace std; 

class CSingleton
{
private:
    static CSingleton* m_pInstance;

    CSingleton()     // The constructor is private
    {
    } 

    CSingleton& operator = (const CSingleton& t);
    CSingleton(const CSingleton &);
public:
    static CSingleton* getInstance()
    {
       if(m_pInstance==NULL)
           m_pInstance= new CSingleton(); 
      
        return m_pInstance;
    }

    void print()
    {
      cout<<this<<endl;   
    }
};

CSingleton* CSingleton::m_pInstance = NULL;

int main()
{
    CSingleton *p1=CSingleton::getInstance();
    CSingleton *p2=CSingleton::getInstance(); 
    CSingleton *p3=CSingleton::getInstance();

    p1->print();
    p2->print();
    p3->print();

    return 0;
}

Run print:

[

0x6e2d18
0x6e2d18
0x6e2d18

]

As can be seen from the printing results, the pointer object points to the same address, realizing that there can only be at most one instance (instance) of a class.

Note: Since instances (instance) exist throughout the life of the system, delete is not needed as long as the system is running

If multiple Csingleton pointer objects call the getInstance() member function at the same time in the case of multithreading, multiple instances will be created since m_pInstance = NULL.

So, in the case of multithreading, you need to use hungry Man implementation

The code is as follows:


class CSingleton
{
private:

    static CSingleton* m_pInstance;

    CSingleton()     // The constructor is private
    {
    }       

    CSingleton& operator = (const CSingleton& t);
    CSingleton(const CSingleton &); 

public:
    static CSingleton* getInstance()
    { 
        return m_pInstance;
    }
};

CSingleton* CSingleton::m_pInstance = new CSingleton;

A singleton class template

What we are explaining now is just a framework, there is nothing in it, which cannot meet the requirements, so we need to write it as a singleton class template header file, when we need a singleton class, we can simply declare the singleton class template header file

Write CSingleton h


#ifndef _SINGLETON_H_
#define _SINGLETON_H_

template <typename T>
class CSingleton
{
private:
    static T* m_pInstance;

    CSingleton()     // The constructor is private
    {   
     }    
    
public:
    static T* getInstance()
    {  
        return m_pInstance;
    }
};

template <typename T>
T* CSingleton<T> :: m_pInstance = new T;

#endif

When we need this singleton class template, we just need to add it as a friend in our own class via friend,

Next, experiment with the singleton class template

Write main cpp


#include <iostream>
#include <string>
#include "CSingleton.h"

using namespace std;

class Test
{
    friend class CSingleton<Test> ; // The statement Test Friends for singleton class templates 
private:  
    string mstr;

    Test(): mstr("abc")
    {
    }

    Test& operator = (const Test& t);
    Test(const Test&);

public:  
    void Setmstr(string t)
    {
     mstr=t;
    }

    void print()
    {
    cout<<"mstr = "<<mstr<<endl;
    cout<<"this = "<<this<<endl;
    }
};

int main()
{
    Test *pt1 = CSingleton<Test>::getInstance();
    Test *pt2 = CSingleton<Test>::getInstance();  

    pt1->print();
    pt2->print();

    pt1->Setmstr("ABCDEFG");
    pt2->print();

    return 0;
}
[

mstr = abc
this = 0x2d2e30

mstr = abc
this = 0x2d2e30

mstr = ABCDEFG
this = 0x2d2e30

]

Related articles: