当前位置:网站首页>Special class design
Special class design
2022-07-25 21:48:00 【The August】
Special class design
Please design a class , Cannot be copied
The copy will only be placed in two scenarios : Copy constructor and assignment operator overload , So you want a class to prohibit copying , Just make the class unable to call copy constructor and assignment operator overload
C++98
Overloading the copy constructor and assignment operator only declares that it does not define , And set its access rights to private .
class CopyBan
{
private:
CopyBan(const CopyBan&);
CopyBan& operator=(const CopyBan&);
};
reason :
- Set private : If only declaration is not set to private, If the user defines it outside the class , You can't prohibit copying
- Just declare not define : Not defined because the function does not call , It doesn't make any sense to define it , It's easy not to write , And if defined, it will not prevent internal copy of member functions .
C++11
C++11 Expand delete Usage of ,delete Except release new In addition to the resources requested , If followed by the default member function =delete, Means to let the compiler delete the default member function .
class CopyBan
{
CopyBan(const CopyBan&) = delete;
CopyBan& operator=(const CopyBan&) = delete;
};
Please design a class , Objects can only be created on the heap
Method 1 :
1. Private the constructor of the class , The copy construct is declared private . Prevent others from calling copy to generate objects on the stack .
2. Provide a static member function , Complete the creation of heap object in the static member function
#include<iostream>
using namespace std;
class OnlyHeap
{
public:
static OnlyHeap* CreateObj()
{
return new OnlyHeap;
}
private:
// Constructor privatization
OnlyHeap()
:_a(0)
{
}
//OnlyHeap(const OnlyHeap& oh);
//OnlyHeap& operator=(OnlyHeap oh);
OnlyHeap(const OnlyHeap& oh) = delete;
OnlyHeap& operator=(OnlyHeap oh) = delete;
private:
int _a;
};
int main()
{
//OnlyHeap oh;
//OnlyHeap* ptr = new OnlyHeap;
OnlyHeap* ptr = OnlyHeap::CreateObj();
//OnlyHeap copy(*ptr);
delete ptr;
return 0;
}
Be careful :
- It is recommended to mainly use this method , Because this design idea is very general
- Provide a static member function after privatizing the constructor , Complete the creation of heap object in the static member function , Otherwise you will fall into “ The thinking of chicken or egg first ” In the middle ( The compiler will report an error )
- This kind of thinking should pay attention to a dead end —— Copy can be used to construct 、 Assign copies to create objects on the stack
- C++98 in Anti copy —— Only declare , Don't realize , Declare private ( But this method can be implemented outside the class , Or you can use improper means to create objects on the stack ( It's not safe ))
- C++11 in Anti copy —— OnlyHeap(const OnlyHeap& oh) = delete; 、OnlyHeap& operator=(OnlyHeap oh) = delete; Whatever the access qualifier is
Method 2 :
1. Private the destructor of the class
2. Provide a member function of , Complete the memory release of the heap object in this member function
#include<iostream>
using namespace std;
class OnlyHeap
{
public:
void DestoryObj()
{
delete this;
//this = nullptr; // Cannot leave empty inside a class
}
private:
~OnlyHeap()
{
cout << "~OnlyHeap()" << endl;
}
private:
int _a;
};
int main()
{
//OnlyHeap oh; // Cannot create on stack
OnlyHeap* ptr = new OnlyHeap;
ptr->DestoryObj();
// In this way, objects cannot be created by copying
//delete ptr; // Release failed
return 0;
}
Be careful :
- This method does not consider copy construction 、 Copy... Copy , As long as the constructor creates a class object, the destructor will be called by default , When the destructor is set to private , Constructor cannot be adjusted , Therefore, objects cannot be created on the stack
Please design a class , Objects can only be created on the stack
Method 1 : Privatization of constructors , Then design static methods to create objects and return .
class StackOnly
{
public:
static StackOnly CreateObj()
{
return StackOnly();
}
private:
StackOnly()
:_a(0)
{
}
private:
int _a;
};
int main()
{
StackOnly so=StackOnly::CreateObj();
// There are some loopholes in this way , Cannot prohibit the creation of objects in static areas
static StackOnly sso=so;
return 0;
}
Method 2 : shielding new because new Call... At the bottom void* operator new(size_t size) function , Just mask the function .
Be careful : To prevent positioning new
class StackOnly
{
public:
StackOnly()
:_a(0)
{
}
private:
void* operator new(size_t size) = delete;
void operator delete(void* ptr) = delete;
private:
int _a;
};
int main()
{
StackOnly so;
//StackOnly* ptr = new StackOnly;
// There are some loopholes in this way , Cannot prohibit the creation of objects in static areas
//static StackOnly sso;
//StackOnly* n = (StackOnly*)malloc(sizeof(StackOnly));
//new(n)StackOnly; // location new
return 0;
}
Be careful : There are some loopholes in these two methods , Cannot prohibit the creation of objects in static areas
Please design a class , uninheritable
C++98 The way : C++98 Privatization of constructors in , The constructor of the base class cannot be derived from the derived class. . Cannot inherit
class NonInherit
{
public:
static NonInherit GetInstance()
{
return NonInherit();
}
private:
// Constructor private
NonInherit()
{
}
};
class Derive : NonInherit
{
};
int main()
{
Derive d;
return 0;
}
summary : C++98 This way is not direct enough , Here is something that can be inherited , however Derive Cannot create object , because Derive Constructor for , You must call the parent class NonInherit structure , however NonInherit The constructor of is private , Private is not visible in subclasses , Then the inheritance here will not report an error , Creating an object of an inherited subclass will report an error
C++11 Method :final keyword ,final decorator , Indicates that the class cannot be inherited .
class NonInherit final
{
};
class Derive : NonInherit // Cannot inherit
{
};
int main()
{
Derive d;
return 0;
}
C++11 In a way that cannot be inherited , intuitive 、 Simple and clear
Please design a class , Only one object can be created ( The singleton pattern )
Design patterns (Design Pattern) It's a set that's been used over and over again 、 Most people know that 、 classified 、 Summary of code design experience .
The purpose of using design patterns : For code reusability 、 Make code easier to understand 、 Ensure code reliability . Design patterns make coding really Engineering ; Design pattern is the foundation of software engineering , Like the structure of a building .
Add : Design patterns : Iterator pattern 、 Adapter pattern 、 Factory mode 、 Observer mode 、 The singleton pattern ……
The singleton pattern :
A class can only create one object , That is, singleton mode , This pattern ensures that there is only one instance of this class in the system , And provide a global access point to access it , The instance is shared by all program modules . For example, in a server program , The configuration information for this server is stored in a file , This configuration data is read uniformly by a singleton object , This singleton object is then used by other objects in the service process to obtain the configuration information , This approach simplifies configuration management in complex environments .
Singleton mode has two implementation modes :
Starving model
That is, whether you use it or not in the future , When the program starts, a unique instance object is created .

The whole situation is unique Singleton Instance object , Then the members in him are the single instance
Starving model
advantage :
- Simple
- If this singleton object is multithreaded (main After the function ) Frequently used in high concurrency environments , High performance requirements , So it's obvious to use the hungry man model to avoid resource competition , Better response speed .
shortcoming :
- Singleton objects main Function before creating an initialized , This may cause the process to start slowly ,
- If there are multiple instances of singleton class objects, the starting order is uncertain .
- If there are multiple singleton classes , And they had dependencies before , So the hungry man model can't guarantee to better control these problems
- Cannot actively free object space
The sluggard model
Not prepared in advance , On first visit , To create a singleton
If singleton object construction is time-consuming or takes up a lot of resources , Such as loading plug-ins , Initialize the network connection , Read files, wait , It is possible that the object will not be used when the program runs , Then it should also be initialized at the beginning of the program , It will cause the program to start very slowly . So in this case, lazy mode is used ( Delay loading ) Better .

The sluggard model The first call GetInstance when , Will create and initialize the singleton object , Compared with the hungry man , There is no problem that may lead to slow startup , You can also control the problem of sequence dependence
The sluggard model :
- advantage :
- When using an instance object for the first time , Create objects . Process startup no load . The startup sequence of multiple single instance instances is freely controlled .
- Compared with the hungry man model , The memory space of the instance object can be automatically released
- shortcoming :
- It's a little more complicated , In particular, we need to control the problem of thread safety ( To use Double-Check Lock by , To ensure efficiency and thread safety .)
Add :
- The singleton pattern : Define a global object , But this method has great defects , This object can only be defined in one .h In file , If this .h In more than one .cpp contain , Then the link will report an error , The reason is that there are many different objects when linking , There will be problems when merging .
- Solution :
- stay .h of use extern Declare global objects , In a .cpp Creating objects in
- stay .h of use static Decorate global objects , But the middle plan is not feasible , Because in multiple .cpp Many different objects will be created in , This is contrary to the problem ( Not an option )
边栏推荐
- CNN structural design skills: taking into account speed accuracy and engineering implementation
- 卸载npm和安装npm_使用`npm uninstall`卸载npm软件包「建议收藏」
- [interview: concurrent Article 23: multithreading: Join] re understanding of join
- Autojs learning - file depth search
- H5 realize the animation effect of a scratch card
- 腾讯云数据库的可信可控之路
- 五、品达通用权限系统__pd-tools-xxs(防跨站脚本攻击)
- Ability to choose
- 开源协议是否具有法律效力?
- 字节一面:TCP 和 UDP 可以使用同一个端口吗?
猜你喜欢

立创EDA——器件的创建01-电阻(二)

【Redis底层解析】链表类型

函数栈帧的创建和销毁

2022 latest examination questions and answers of eight members (standard staff) of Shanghai Architecture

On Web Performance Optimization (1)

My heart's broken! After being cheated by 30000, a 16-year-old girl was unconvinced and cheated by 50000

人脸与关键点检测:YOLO5Face实战

少儿编程 电子学会图形化编程等级考试Scratch一级真题解析(判断题)2022年6月

Oracle RAC RMAN backup error ora-19501 ora-15081
![[MAIXPY]kpu: load error:2005, ERR_READ_FILE: read file failed问题解决](/img/0b/da67b5a361a2cdfaf81568d34cf5f7.png)
[MAIXPY]kpu: load error:2005, ERR_READ_FILE: read file failed问题解决
随机推荐
Guys, how can Flink SQL submit tasks in per job mode?
The inexplicability of Intel disassembly
[MAIXPY]kpu: load error:2005, ERR_ READ_ File: read file failed problem solving
PE format: analyze and implement IATHOOK
GPON introduction and Huawei OLT gateway registration and configuration process
Intel base instruction -- bnd
[redis underlying parsing] linked list type
函数栈帧的创建和销毁
How to solve the problem of high concurrency and large traffic with PHP
Oxford University: many common insomnia drugs lack long-term safety data
【面试:并发篇24:多线程:综合练习】顺序控制
【饭谈】如何设计好一款测试平台?
My heart's broken! After being cheated by 30000, a 16-year-old girl was unconvinced and cheated by 50000
MPI学习笔记(二):矩阵相乘的两种实现方法
若依如何解决导出使用下载插件出现异常?
Oracle RAC RMAN backup error ora-19501 ora-15081
Isn't it too much to play Gobang in idea?
如何用 Redis 实现分布式锁的?
Optimization analysis of storage structure and IO performance of openharmony littlefs file system
Handwriting distributed configuration center (1)