当前位置:网站首页>Singleton pattern and special class design
Singleton pattern and special class design
2022-06-10 14:09:00 【Which bug are you?】
List of articles
The singleton pattern
What is singleton mode
The singleton pattern (Singleton), Make sure there is only one instance of a class , And provide a global access point to access it .– Big talk design patterns
Application scenarios
Ensure that a class has only one instance
Such as Windows Task manager under , Recycle bin, etc .
Log management , Counter, etc .
In short , When you need a unique instance, you can consider the singleton pattern . In this way, it can strictly control how and when customers access it , Controlled access to unique instances .
Advantages and disadvantages
advantage
- Reduce memory overhead , Because there is only one instance in the system .
- Avoid frequent creation and destruction of objects , Improved performance
- Avoid multiple USES of resources , For example, in a single instance, multiple people only write one log file , If there are multiple log files, it may cause the same log file to be written
- Set global access point
shortcoming
- Too much responsibility , Conflicts with a single responsibility
- Cannot inherit ( Constructor private )
Realization
Singleton mode has two implementation modes , Lazy mode and hungry mode .
Note the concept of the singleton pattern , It is probably the only instance with a global access point , Let's start with these two points .
The only example : Constructor private + Anti copy
Copy construction is a form of construction , So we need to prevent , Constructor private does not allow others new.
Global access point : Give a public interface
Starving model
Simply speaking , Make things right from the start , Take it when you need it .
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton& GetInstance()
{
return _instance;
}
int GetRandom()// Since the emphasis is not on random numbers So go straight back to a 30
{
return 30;
}
private:
Singleton() {}// Constructor private
Singleton(Singleton&) = delete;// Anti copy , By =delete Modifier indicates that this function is deleted , That is, you can only declare that you do not implement , In other words, the function is disabled
Singleton& operator=(const Singleton&) = delete;// Anti copy
static Singleton _instance;
};
Singleton Singleton::_instance;// Class must be initialized , Class just declares
int main()
{
//1. call
cout<<Singleton::GetInstance().GetRandom()<<endl;
//2.
Singleton& s = Singleton::GetInstance();
cout<<s.GetRandom()<<endl;
return 0;
}
After copy prevention and constructor privatization, the following methods fail
Singleton s;//err
Singleton s1(s);//err
Singleton s1=s;//err
From the above, we can see the advantages and disadvantages of the hungry man model , The obvious thing is that the implementation is simple and crude , The disadvantages are obvious , When the class is loaded, the singleton object has been generated , That is, it has been loaded before it is used , For example, this resource is very large , Load when the game starts , That will cause the game to start very slowly . And if there are multiple singleton objects, the instantiation order is uncertain when starting ( The instantiation order of singleton objects in different source file classes is uncertain , The lazy man model solves this problem , Because the instantiation of lazy pattern is inside the function , The order of instantiation can be solved by calling the function ).
Class loading static initialization solves the thread safety problem .
The sluggard model
Cook whenever you need to , And then eat .
class Singleton
{
public:
static Singleton* GetInstance()
{
if (_instance == nullptr)
{
_mtx.lock();//double lock Ensure thread safety
if (_instance == nullptr)// It has to be checked again Otherwise, another thread may have new Finished , Here again new Single case violation , And may overwrite the data .
{
_instance = new Singleton();
}
_mtx.unlock();
}
return _instance;
}
int GetRandom()
{
return 30;
}
class Clear// Internal class of resource recycling , Must be public , Otherwise, an error is reported in the external statement
{
public:
~Clear()
{
cout << " Release resources " << endl;
delete _instance;
}
};
private:
static Clear _cle;
Singleton() {}
Singleton(Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* _instance;
static mutex _mtx;// Thread safety
};
Singleton* Singleton::_instance = nullptr;
mutex Singleton::_mtx;
Singleton::Clear _cle;
int main()
{
//1.
cout<<Singleton::GetInstance()->GetRandom()<<endl;
//2/
static Singleton* s = Singleton::GetInstance();
cout << s->GetRandom() << endl;
// The reason for receiving cannot be referenced with an lvalue The return value is the right value You have to use the right value reference to receive
// Why is the return value of a function an R-value Because the return value is returned with the help of temporary variables, the address cannot be obtained
// If the return value is an lvalue reference, it can be received with an lvalue reference
return 0;
}
The advantages and disadvantages of the lazy man model are also obvious , The advantage is that you can instantiate it whenever you first use it , In addition, the order of instantiation of multiple singleton objects can be solved by calling functions , The disadvantage is that it is complicated to write , Consider thread safety and memory leaks . Lazy people use pointers to better recycle resources ( The hungry man uses the object )
Lazy people may lose data because of multithreading , Thread locking ensures that there must be only one thread in a multithreaded environment new object , Only one singleton object is created , Locking may cause frequent context switching ,double lock solve .
Special class design
We usually use constructors , Copy constructs and assign overloads to create objects , Now all these methods are disabled , Then write an external callable interface to define the creation method of the class .
Of course, there are other ways , This can often be used as a general idea .
The following disallowances apply C++11 Of delete Keyword implementation , The function is to prevent the compiler from generating the default function version , That is, there is a declaration but no implementation .
Designing a class can only create objects on the heap
Simply put, it can only be done through new To create objects .
Method 1
Constructor disabled , Then give an interface for external calls .
Disabling the constructor = Constructor private + Disable copy construction + Disable assignment overloading
class HeapOnly
{
public:
static HeapOnly* GetInstance()
{
return new HeapOnly;
}
void Test()
{
cout << "I am Test" << endl;
}
private:
HeapOnly() {}
HeapOnly(HeapOnly&) = delete;
HeapOnly& operator=(const HeapOnly&) = delete;
};
int main()
{
HeapOnly* ho = HeapOnly::GetInstance();
ho->Test();
delete ho;
return 0;
}

Method 2
Destructors are private
Objects are built on the stack , The compiler allocates space , The compiler manages the life cycle of objects , After the object is used, the compiler will check all non static functions of the object , Including destructors , When the compiler finds that the destructor cannot be accessed, it cannot reclaim this space , So the compiler cannot allocate space for it , The compiler will also report an error when it detects this condition .
Destructor private methods are not recommended , Because it cannot be used outside the class delete Release space , Easy to cause memory leaks .
class HeapOnly
{
public:
void Test()
{
cout << "I am Test" << endl;
}
private:
~HeapOnly();
};
int main()
{
//HeapOnly ho_stack;//err
HeapOnly* ho = new HeapOnly;
ho->Test();
return 0;
}

Objects can only be created on the stack
Method 1
Out of commission new --> heavy load operator new that will do .
There is a flaw in this , You can still create objects in the static area

Method 2
Make the constructor private and customize an interface
There is no need to disable constructors here , Copy structure , Assignment overload , Because for the following scenario , The copy construction of anonymous objects is more in line with the scenario , The compiler selects the copy construct to construct , So if we disable copy construction, an error will be reported , Because of our delete The keyword is declarative but not implementable , It is not true that this function is deleted with the declaration . therefore StackOnly() Once we see that there is a copy construct declaration written by ourselves, we will match the copy construct , If the copy structure we wrote does not implement the copy function, an error will be reported .
Understanding this is related to the knowledge of compiling links , The compiler sees the declaration and matches it , Instead of having to see the function implementation to match , Link time will find the implementation , When it is found that there is a declaration but no implementation, it is easy to lead to link errors .

A class cannot be inherited
The parent constructor is private , When constructing, first construct the parent class and then the child class , The parent class cannot construct and cannot inherit .
Last
About singleton mode , It can be said that only one object can be created .
There's a little problem , Why not use global variables instead of singleton mode , Just define a unique variable globally , Reasonable [doge], In theory , But very not recommended , You can find the information yourself " Why not recommend using global variables ".
The use of global variables can cause many problems , And it's easy to create links 、 Redefinition and other errors , If someone gives this variable another alias when multiple people collaborate , The time price of maintaining code is too high , This is only a small drawback of global variables .
Global variables are also not recommended in the Niuke code specification score , Of course, the code is not that long when writing questions , A few global variables don't matter .
.h Cannot contain definition , Or more cpp To include will lead to link errors , Try to separate definitions from declarations
【82】【Cherno C++】【 Chinese characters 】C++ Single instance mode of _ Bili, Bili _bilibili
边栏推荐
- QT将接收到的json数据(含中文)unicode转utf8
- Leetcode 829. Sum of continuous integers
- UE5如何将屏幕坐标转为世界坐标和世界方向
- [note] about the problem of insufficient compilation mapping memory in keil
- CVPR 2022 | 基于序列对比学习的长视频逐帧动作表示
- Markdown Title centered
- How to solve the problem that vmware tools are grayed out when VMware Workstation is installed
- 【笔记】关于keil中的出现的编译映射内存不足的问题
- Bottomnavigationview is used in conjunction with viewpager, to modify icon size, to remove text, etc
- Kotlin bubbling algorithm, Gaud map filters out the data whose distance between two points is less than 50, and does not repeat the display
猜你喜欢

5.8G微波雷达模块使用,5.8G微波雷达模块工作原理和介绍

Simulated 100 questions and online simulated examination for safety production management personnel of hazardous chemical production units in 2022

【离散数学期复习系列】三、集合的概念及运算

Docker部署一个Redis集群

2022 high frequency software test interview questions of large factories (with answers)

北京/上海内推 | 微软亚洲研究院系统与网络组招聘全职实习生

2022危险化学品经营单位主要负责人考试题库及在线模拟考试

一次主从表集成流程开发过程

C#多线程学习笔记二
![[discrete mathematics review series] i. propositional logic](/img/ae/7f062cfa416a26be3d32dfb1353c80.png)
[discrete mathematics review series] i. propositional logic
随机推荐
为doc2vec生成训练向量的数据集
多云管理平台cmp是什么意思?谁能清楚解释一下
Flutter Listview, Column, Row学习个人总结2
C#多线程学习笔记一
Bottomnavigationview is used in conjunction with viewpager, to modify icon size, to remove text, etc
Textinputlayout usage details
【大咖秀】博睿数据眼中的AIOps,选择正确的赛道正确的人
QT将接收到的json数据(含中文)unicode转utf8
[notes] notes on C language array pointer, structure + two-dimensional array pointer
1
[Chongqing University] information sharing of preliminary and second examinations (with postgraduate entrance examination group)
618. How to prepare for the great promotion
Leetcode-56-merge interval
架构实战营 第 6 期 模块八课后作业
技术分享| 快对讲,全球对讲
Operation of simulated examination platform for theoretical question bank of refrigeration and air conditioning equipment operation in 2022
Still saying that university rankings are a joke? The latest regulation: Top50 universities in the world can be directly settled in Shanghai!
5.8G微波雷达模块使用,5.8G微波雷达模块工作原理和介绍
[operation tutorial] how to correctly use the Hikvision demo tool to configure the channel to go online?
Flutter drawer学习总结6