Create singleton mode

Singleton pattern: ensure that a class has only one instance and provide a global access point to access it.

Singleton mode

1: What is a singleton

My understanding: during the running of the program, only one instance is constructed, and all users share and use the instance.

Singleton pattern: ensure that a class has only one instance and provide a global access point to access it.

2: How to implement singleton

Characteristics of singleton:

1: globally unique object = = "is implemented with static member variable or scope feature

2: users are not allowed to construct = = "disable the constructor, but ensure that they can call it

3: only corresponding interfaces are provided, and users are not allowed to modify = = "disable related copy structures, etc

4: multithreading should be safe. Release of resources = = "lock, release of static objects in the same scope, and call the corresponding destructor at the end of program running

utilize static Features to implement singleton mode.
	1: Static members are shared by all objects and do not belong to a single instance
	2: Static members must be defined outside the class and do not need to be added static,It has been added at the time of declaration
	3: Class static members are available class names::Static member or object.Static members to access
	4: Static member functions have no hidden this Pointer, cannot access any non static members
	5: Static members, like ordinary members of a class, have public,protected,private3 An access level that can also have a return value

The implementation of the singleton mainly depends on the static feature!!!

3: Coding implementation

Control the application and release of memory on the stack, and realize the single instance of lazy and hungry modes with the help of static feature (all objects are shared and do not belong to an instance)

hungry man:

#include <iostream>
using namespace std;

class Singleton{
private:
	Singleton() = default;
	Singleton(const Singleton & s) = delete;
	Singleton &operator = (const Singleton &s) = delete;
	~Singleton(){};
private:
	static Singleton m_sig;

public:
	static Singleton * GetInstence()
	{
		return &m_sig;
	}

	void Print()
	{
		cout<<"Singleton Instence\n ";
	}
};

Singleton Singleton::m_sig; //hungry man

int main()
{
	Singleton::GetInstence()->Print();
	return 0;
}

Sluggard: static serves the whole class, not an object. It is initialized only once, and the life cycle is extended until the end of the whole program. The global data area allocates memory

When decorating global variables, they can only be accessed in this file

#include <iostream>
using namespace std;

class Singleton{
private:
	Singleton() = default;
	Singleton(const Singleton & s) = delete;
	Singleton &operator = (const Singleton &s) = delete;
	~Singleton(){};

public:
	static Singleton * GetInstence() //static takes effect when this function is called
	{
		static Singleton m_sig;
		return &m_sig;
	}

	void Print()
	{
		cout<<"Singleton Instence\n ";
	}
};

int main()
{
	Singleton::GetInstence()->Print();
	return 0;
}

The static feature can be used to save the address of the corresponding heap memory on the stack, and the static feature and the C + + destructor feature can be used to automatically release the memory applied on the heap when the program terminates. The related implementations are as follows:

The following code manages the heap memory with static, but it is obvious that the resources from new are not released,

#include <iostream>
#include <mutex>
using namespace std;

class Singleton{
private:
	Singleton() = default;
	Singleton(const Singleton & s) = delete;
	Singleton &operator = (const Singleton &s) = delete;
	~Singleton(){};

public:
	//It operates on static members, so it is controlled as static
	static Singleton * GetInstence()
	{
		if(Singleton::m_sig_instance == NULL)
		{
			m_mutex.lock();
			if(Singleton::m_sig_instance == NULL)
			{
				m_sig_instance = new Singleton();
			}
			m_mutex.unlock();
		}
	}

	void Print()
	{
		cout<<"Singleton Instence.\n ";
	}

private:
	static Singleton * m_sig_instance;
	static std::mutex m_mutex;
};

Singleton * Singleton::m_sig_instance = NULL;
std::mutex Singleton::m_mutex;
int main()
{
	Singleton::GetInstence()->Print();
	return 0;
}

With the stack feature of static and the scope of the class, the static feature is used to release resources within the scope of the class:

#include <iostream>
#include <mutex>
using namespace std;

class Singleton{
private:
	Singleton() = default;
	Singleton(const Singleton & s) = delete;
	Singleton &operator = (const Singleton &s) = delete;
	~Singleton(){};

	class FreeSingleton
	{
		public:
			~FreeSingleton()
			{
				cout<<"start free singletion \n";
				if(m_sig_instance != NULL)
				{
					cout<<"free singletion \n";
					delete m_sig_instance;
					m_sig_instance = NULL;
				}
			}
	};

public:
	//It operates on static members, so it is controlled as static
	static Singleton * GetInstence()
	{
		if(Singleton::m_sig_instance == NULL)
		{
			m_mutex.lock();
			if(Singleton::m_sig_instance == NULL)
			{
				m_sig_instance = new Singleton();
			}
			m_mutex.unlock();
		}
	}

	void Print()
	{
		cout<<"Singleton Instence.\n ";
	}

private:
	static Singleton * m_sig_instance;
	static std::mutex m_mutex;
	static FreeSingleton m_freed;

};

Singleton * Singleton::m_sig_instance = NULL;
std::mutex Singleton::m_mutex;
//With the help of the characteristics of static stack, release the corresponding memory through destruct. Pay attention to the type here and the scope value of static variable
Singleton::FreeSingleton Singleton::m_freed; 

int main()
{
	Singleton::GetInstence()->Print();
	return 0;
}

Keywords: C++ Design Pattern

Added by chuckjones on Fri, 14 Jan 2022 05:51:22 +0200