当前位置:网站首页>Description and simple implementation of intelligent pointer
Description and simple implementation of intelligent pointer
2022-07-18 01:43:00 【Wuhu kaichong ~】
The code of this blog is in vs2022 The following debugging and implementation
Catalog
Why smart pointers are needed ?
auto_ptr The implementation of the
98 edition auto_ptr( Above code ) The problem of
Later revised auto_ptr The problem of
Why smart pointers are needed ?
Because we can easily forget to release the resources managed by the pointer , This can easily lead to resource leakage
RAII
Mention smart pointers , I have to mention it RAII, It's an idea
RAII(Resource Acquisition Is Initialization) Is the use of object life cycle to control program resources ( Such as memory 、 File handle 、 network connections 、 Mutexes and so on ) Simple technique .
Get resources at the time of object construction , Access to the resource is then controlled to remain valid throughout the life cycle of the object , Finally, the resources are released when the object is destructed . by means of , We actually trust the responsibility of managing a resource to an object . There are two advantages to this approach :
There is no need to explicitly release resources .
In this way , The resources required by an object remain valid throughout its lifetime .
To put it bluntly , Is to package resources , Using the characteristics of destructors , To help us release resources
auto_ptr
auto_ptr The implementation of the
#pragma once
namespace czz {
template <class T>
class auto_ptr {
public:
auto_ptr(T* ptr = nullptr)
:_ptr(ptr)
, _isOwner(false)
{
if (_ptr != nullptr) {
_isOwner = true;
}
}
~auto_ptr() {
if (_ptr != nullptr && _isOwner == true) {
delete _ptr;
_ptr = nullptr;
}
}
T& operator*() {
return *_ptr;
}
T* operator->() {
return _ptr;
}
// Solve the problem of resource release : Resource transfer
auto_ptr(const auto_ptr<T>& ap)
:_ptr(ap._ptr)
, _isOwner(ap._isOwner) {
ap._isOwner = false;
}
auto_ptr<T>& operator=(const auto_ptr<T>& ap) {
if (this != &ap) {
if (_ptr != nullptr && _isOwner == true) {
delete _ptr;
}
_ptr = ap._ptr;
_isOwner = ap._isOwner;
ap._isOwner = false;
}
return *this;
}
private:
T* _ptr;
//_isOwner There are two uses , Determine whether the resource exists , And whether this object has the release right ;
mutable bool _isOwner;
};
}Yes auto_ptr The study of
Let's talk about history first ,auto_ptr yes c++98 The concept proposed in , It was changed once in the later amendment , But in the end, it was changed back . Later, the suggestion given by the standard library is : Under no circumstances is it recommended to use .
Since we change things around , It means there is a problem , And it hasn't been solved yet , Therefore, it is not recommended to use under any circumstances .
98 edition auto_ptr( Above code ) The problem of
We know , One class , There should be copy construction and assignment operator overloading , The pointer to the package , Shallow copy is definitely not good , Because it involves the management of resources , If two objects use one resource , Which one releases resources , What about the other one ? therefore 98 The solution to this problem is resource transfer , It is when copying construction or overloading assignment operators , Give the resources of the previous object to the next object , But there is also a problem : Two pointers cannot point to the same resource at the same time .
Later revised auto_ptr The problem of
correct , Nature is to solve the problems ahead , How is that corrected , Just follow the code above , That is, everyone can use , But only one is entitled to release , But now the problem is even bigger , It may directly cause the wild pointer , For example, the resources have been released , Then use other pointers to this resource , therefore c++11 It went back . that c++11 What the hell happened , Let people give up using auto_ptr Well ? To look down .
unique_ptr
unique_ptr Realization
Simply let us see an idea
#pragma once
namespace czz {
template <class T>
class unique_ptr {
public:
unique_ptr(T* ptr)
:_ptr(ptr)
{}
~unique_ptr() {
if (_ptr != nullptr) {
delete _ptr;
_ptr = nullptr;
}
}
unique_ptr(const unique_ptr<T>& up) = delete;
unique_ptr<T>& operator=(const unique_ptr<T>& up) = delete;
T& operator*() {
return *_ptr;
}
T* operator->() {
return _ptr;
}
private:
T* _ptr;
};
}I believe you can understand , Copy construction and assignment operator overloading are not allowed directly , There's nothing to say about this , To use , The only pity is that a resource can only be managed by one pointer
shared_ptr
This is to solve the above problem , For resource issues , That is, it involves copy construction and assignment operator overloading , It uses reference counting , Look at the code first
shared_ptr The implementation of the
#pragma once
#include <mutex>
namespace czz {
template<class T>
struct DFDef {
void operator()(T*& ptr) {
if (ptr) {
delete ptr;
ptr = nullptr;
}
}
};
template <class T, class DF = DFDef<T>> // Maybe the resource is not new Of , So we need other ways to release
class shared_ptr {
public:
shared_ptr(T* ptr = nullptr)
:_ptr(ptr), _pRefCount(nullptr), _pMutex(nullptr) {
if (_ptr) {
_pRefCount = new int(1);
_pMutex = new std::mutex;
}
}
~shared_ptr() {
Release();
}
T& operator*() {
return *_ptr;
}
T* operator->() {
return _ptr;
}
shared_ptr(const shared_ptr<T, DF>& sp)
:_ptr(sp._ptr), _pRefCount(sp._pRefCount) {
_pMutex = new std::mutex;
AddRef();
}
shared_ptr<T, DF>& operator=(const shared_ptr<T, DF>& sp) {
if (_ptr != sp._ptr) {
Release();
_ptr = sp._ptr;
_pRefCount = sp._pRefCount;
_pMutex = new std::mutex;
AddRef();
}
return *this;
}
size_t use_count()const {
return *_pRefCount;
}
T* Get() {
return _ptr;
}
private:
void AddRef() {
if (_pRefCount != nullptr) {
_pMutex->lock();
++(*_pRefCount);
_pMutex->unlock();
}
}
int SubRef() {
_pMutex->lock();
--(*_pRefCount);
_pMutex->unlock();
return *_pRefCount;
}
void Release() {
if (_ptr != nullptr && SubRef() == 0) {
DF()(_ptr);
delete _pRefCount;
delete _pMutex;
_ptr = nullptr;
_pRefCount = nullptr;
}
}
private:
T* _ptr;
int* _pRefCount;
std::mutex* _pMutex;
};
}shared_ptr The problem of
Let's take a chestnut :
For a node of a bidirectional linked list , We can point the inside itself and the two inside it forward (prev) after (next) The pointer of is changed to shared_ptr, Now there is a linked list with two nodes ,A Node next Point to B node ,B Node prev Point to A node , Now don't B The node , Its reference count is minus 1, But because A Node next And point here B Node things , therefore B The resources of a node cannot be directly released , Empathy ,A The nodes are the same , And deduce , You'll find that , In this case , In any case, these two resources cannot be released
The solution to the problem
weak_ptr: This is a special solution shared_ptr Of , It's also very simple. , That is, only the main resources adopt shared_ptr, Others use weak_ptr That's it , In the example above , For the node itself , We use it shared_ptr management , In the node, such as prev and next, We take weak_ptr That's all right. , As for the principle , Say something about it , That is, reference counting is not actually a , It's two , A management shared_ptr, A management weak_ptr
边栏推荐
- 【C 练习】喝汽水
- VDD,VCC,VSS,GND,地之间有何区别?
- How Axure achieves screen adaptation
- 搜索结果页竞价广告展现升级,对SEO有什么影响?
- [practice C] xiaolele walks up the steps
- 计算方法工程数学第一节课Doolittle
- 容器介绍及总结
- A Tong's little wish
- Cloud mall source code repair 30 sets of templates to support one click docking of major systems
- Summary of Halcon common image preprocessing operators
猜你喜欢

Redis transaction and Message Subscription Publishing

高权重没备案网站,批量降权,正常吗?

Introduction to redis

Say goodbye to Leica, Huawei opens a new era! Netizen: Xiaomi

企业站,有排名,没有流量,怎么办?

【C 练习】打印‘X’图形

【C】 Address of array

Cloud mall source code repair 30 sets of templates to support one click docking of major systems

How can Volvo be confident to maintain "zero casualties" in traffic safety in the era of electrification?

【C】数组的地址
随机推荐
System.arraycopy的使用和参数含义详解
【C 练习】求n的k次方(递归实现)
【C】 Creation and destruction of function stack frames
网络安全(2)
在线综艺冷场:“爱优腾芒”放不开,“抖快B”拿不下
【C 练习】下列代码输出的结果是什么
【C 练习】序列中删除指定的数字
Reasons for persisting in writing
STM32 application development practice tutorial: application development of environmental temperature and humidity monitoring
【C】指针进阶
[C exercise] print all "Narcissus numbers" from 0 to 100000
Solution of in multi column special query type in laravel
Calculation method engineering mathematics first lesson Doolittle
WinForm控件属性大全
Node connects to the database for addition, deletion, modification and query
Network security (2)
今日睡眠质量记录80分
Cloud native: docker practical experience (III) deploy MySQL 8 master-slave replication on docker
求字符串长度
nosql概述