当前位置:网站首页>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
边栏推荐
- Leetcode-56-merge interval
- Qualcomm has finally begun to develop its own core architecture after learning from the difficulties of assembling chips to maintain its competitive advantage
- 组装芯片难保竞争优势,痛定思痛的高通终于开始自研核心架构
- [C language] pointer function, function pointer and array function
- C#多线程学习笔记三
- Markdown Title centered
- Yanrong looks at how to realize the optimal storage solution of data Lake in a hybrid cloud environment
- 5.8G微波雷达模块使用,5.8G微波雷达模块工作原理和介绍
- 在启牛开户安全么
- P3379 [template] nearest common ancestor (LCA)
猜你喜欢

2022 Shandong Province safety officer C certificate retraining question bank and online simulation examination

【重庆大学】初试复试资料分享(附考研群)

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

Flutter 页面跳转 传参,TabBar学习总结5

Still saying that university rankings are a joke? The latest regulation: Top50 universities in the world can be directly settled in Shanghai!

算力网络照进现实,浩鲸科技如何构建?

22.6.7成功使用doc2vec模型生成嵌入向量

The relocation of Apple's production line shows that 5g industrial interconnection and intelligent manufacturing have limited help for manufacturing in China

Mmdetection adds precision to the evaluation index

组装芯片难保竞争优势,痛定思痛的高通终于开始自研核心架构
随机推荐
Textinputlayout usage details
Leetcode 2293. Minimax game (yes. One pass)
Flutter Wrap Button bottomNavigationBar学习总结4
架构实战营 第 6 期 模块八课后作业
Qualcomm has finally begun to develop its own core architecture after learning from the difficulties of assembling chips to maintain its competitive advantage
Operation of simulated examination platform for theoretical question bank of refrigeration and air conditioning equipment operation in 2022
Flutter Icon Stack LIsttitle...学习总结3
40 necessary methodologies for large factories
New features mail GPU counter module adds GPU primitive processing and GPU shader cycles
大厂面试上午10:00面试,10:09就出来了 ,问的实在是太...
【解决】每次加载已经训练好的模型,生成的向量会有不同
Microsoft Word 教程,如何在 Word 中更改页边距、创建新闻稿栏?
自适应功能简略
UE5如何将屏幕坐标转为世界坐标和世界方向
大厂必备的40个方法论
Ue5 Comment convertir les coordonnées de l'écran en coordonnées du monde et en direction du monde
C#多线程学习笔记一
C # list of shallow copy and deep copy customized classes <>
Flutter Listview, Column, Row学习个人总结2
Allan方差与随机误差辨识