<> Smart pointer

Input questions :
Given a string , I don't know how many characters there are , How to input ?
use cin.getline(); Enter a line .

<> Smart pointer concept

Smart pointer is mainly an object-oriented encapsulation of bare pointer , Initialize the resource address in the constructor , Free resources in destructor . When resources should be released , A smart pointer to it ensures that it is automatically released .

<>RAII

RAII Automated management of heap space —— Using the mechanism of automatic object deconstruction .

malloc, new Dynamically allocated objects such as , It's very likely that you forgot to release resources, resulting in leakage .
For an object , Apply for space in constructor , And in the destructor ( Called when leaving the scope ) Free up space when you need it , that is RAII Resource acquisition as initialization Technology .

C++11 Introducing smart pointers , Use reference count , Let programmers no longer need to care about manually freeing memory .

<> Reference count

This count is generated to prevent memory leakage .

For dynamically assigned objects , Count references , Every time you add a reference to the same object , Then the reference count is incremented once , Every time you delete a reference , The reference count is decremented by one , When the reference count of an object is 0 Time , The heap memory pointed to will be automatically deleted .

be careful : Reference count is not garbage collection , Reference counting can reclaim objects that are no longer in use as soon as possible , At the same time, there will be no long waiting time in the recycling process , It can more clearly indicate the life cycle of resources .

<> Bare pointer
int *ptr;
This kind of pointer is called bare pointer .
There are some shortcomings in using bare pointers :

*
If the bare pointer is used to allocate memory , Forget to release resources manually , Memory leaks occur .

*
If multiple raw pointers are used to point to the same resource , One of the pointers releases the resource , Other pointers become dangling pointers , If you release it again, there will be an error .

*
If the program exits abnormally , The code for releasing resources of bare pointer failed to execute , It can also cause memory leaks .

<> Classification of smart pointers

Header file needs to be imported #include< memory > Smart pointer

<> Smart pointer without reference count auto_ptr

Abandoned

* The same bare pointer cannot be used for assignment / Initialize multiple auto_ptr;
* Copy construction and equal sign operator —— Set the original smart pointer to null ;
* Implicit construction is not allowed ;
auto_ptr By putting everything except the last one auto_ptr Set nullptr To avoid shallow copies , Its resource ownership can be transferred .
void fun() { int* p = new int(10); auto_ptr<int> a_p(p);
//a_p On stack frame , It will automatically destruct , It'll be on the pile p delete //auto_ptr<int> a_p1(p); collapse
The same bare pointer cannot be used for assignment / Initialize multiple auto_ptr //auto_ptr<int> a_p = p; // copy construction Implicit construction , Push by type /*
p Generate temporary auto_ptr object —— Implicit construction Copy constructs using temporary objects a_p Destruct temporary object —— optimization -- Direct construction a_p */ //a_p=a_p2; Equal sign operator overload
auto_ptr<int> a_p = auto_ptr<int>(p);// Explicit construction cout << *p << endl; cout << *a_p <<
endl; a_p.release();// Returns the current address , And set the current smart pointer to null a_p.reset();// Release the memory pointed to by the current smart pointer , Null pointer
a_p.get();// Get smart pointer internal pointer }
//auto_ptr a_p = p; copy construction Implicit construction is not allowed , Push by type
*p Generate temporary auto_ptr object —— Implicit construction * Copy constructs using temporary objects a_p * Destruct temporary object * —— optimization -- Direct construction a_p
auto_ptr a_p = auto_ptr §; Explicit construction

<> Simulation Implementation mauto_ptr
#ifndef MAUTO_PTR_H #define MAUTO_PTR_H template<typename T> class Mauto_ptr {
public: explicit Mauto_ptr(T*ptr=nullptr)//explicit Prevent implicit construction :_ptr(ptr) {}
Mauto_ptr(Mauto_ptr& src) :_ptr(src.release()) {} Mauto_ptr& operator=(Mauto_ptr
& src)// Equal sign operator overload { _ptr = src.release(); } ~Mauto_ptr() { delete_ptr; } T*
release() { T* tmp = _ptr; _ptr = NULL; return tmp; } void reset() { delete_ptr;
_ptr= NULL; } T& operator*()// Dereference operator { return *_ptr; } T* operator->()
// Arrow operator , Is a second call { return _ptr; } private: T* _ptr; }; #endif
<> Smart pointer without reference count unique_ptr

C++ 11

* The same bare pointer cannot be used for assignment / Initialize multiple unique_ptr;
* Implicit construction is not allowed ;
* Copying construction is not allowed , Overloading of the equal sign operator is not allowed ;
unique_ptr Deleted copy construction and assignment function , Therefore, ordinary copy or assignment operations are not supported .
Copy construction with right value reference and overloading of equal sign operator are introduced , Can put unique_ptr As the return value of the function .
// rvalue reference Used to reference a dying object —— Temporary object unique_ptr<int>fun(unique_ptr<int>& ptr) { cout << *
ptr<< endl; int* p = new int(9); return unique_ptr<int>(p); } void fun() { int*
p= new int(10); unique_ptr<int> u_p; //unique_ptr<int> u_p=p; Implicit construction is not allowed
//unique_ptr<int> u_p(u_p1); Copying construction is not allowed //u_p1=u_p ; Overloading of the equal sign operator is not allowed unique_ptr<int> u_p(p
); //unique_ptr<int> u_p(new int(10)); cout << *p << endl; cout << *u_p << endl;
u_p.get(); u_p.release(); u_p.reset(); //u_p.swap(); Swap two smart pointers unique_ptr<int>
u_p2(fun(u_p)); u_p2 = fun(u_p); cout << *u_p2 << endl; }
rvalue reference Used to reference a dying object —— Temporary object
const int& a = 10; int&& b = 10;
<> Simulation Implementation unique_ptr
#ifndef MUNIQUE_PTR_H #define MUNIQUE_PTR_H template<typename T> class
Munique_ptr{ public: explicit Munique_ptr(T* ptr = nullptr) :_ptr(ptr) {}
//Munique_ptr(Munique_ptr& src) = delete; //Munique_ptr& operator=(Munique_ptr&
src) = delete; Munique_ptr(Munique_ptr&& src)// rvalue reference , Reference to dying objects :_ptr(src.release(
)) { } Munique_ptr& operator=(Mauto_ptr&& src) { _ptr = src.release(); } ~
Munique_ptr() { delete_ptr; } T* release() { T* tmp = _ptr; _ptr = NULL; return
tmp; } void reset() { delete_ptr; _ptr = NULL; } T& operator*() { return *_ptr;
} T* operator->()// Arrow operator , Is a second call { return _ptr; } operator bool()//bool heavy load no return value {
return _ptr != NULL; } private: T* _ptr; }; #endif
<> Smart pointer with reference count shared_ptr—— Strong intelligent pointer

* Implicit construction is not allowed ;
* The same bare pointer cannot be used for assignment / Initialize multiple shared_ptr;
* Allow copy construction , Allow equal sign operator overloading ;
One shared_ptr When referencing resources , The reference count of the resource is incremented by one , Typically used to manage the lifecycle of objects . As long as there is one pointing to the object shared_ptr
existence , The object will not destruct .
#include<iostream> #include<map> #include<memory>// Smart pointer #include"mshared_ptr.h"
using namespace std; template<typename T> map<T*, int> Mshared_ptr<T>::_count =
new map<T*,int>(); void fun() { int* p = new int(11); shared_ptr<int> s_p(p);
shared_ptr<int> s_p1(s_p);// Allow copy construction s_p = s_p1;// Allow equal sign operator overloading cout << s_p.use_count(
) << endl;// Reference counter cout << *p << endl; cout << *s_p << endl; cout << *s_p1 <<
endl; s_p.unique();// Determine whether the current is unique }
<> Simulation Implementation shared_ptr
#ifndef MSHARED_PTR_H #define MSHARED_PTR_H template<typename T> class
Mshared_ptr{ public: explicit Mshared_ptr(T* ptr = nullptr) :_ptr(ptr) {}
Mshared_ptr(Mshared_ptr& src) { /* // The return value is pair Determine whether the insertion is successful ==1 Insert successful ,==0 Insert failed if
(_count.insert(make_pair(_ptr, 2)).second == 0) { _count[_ptr]++; } */ _count.
insert(make_pair(_ptr, 1)); _count[_ptr]++; _ptr = src._ptr; } Mshared_ptr&
operator=(Mshared_ptr&& src) { if (_ptr == src._ptr) { return *this; } if (
unique()) { _count.erase(_ptr); delete _ptr; } else { _count[_ptr]--; } _ptr =
src._ptr; } ~Mshared_ptr() { if (unique()) { _count.erase(_ptr); delete _ptr; }
else { _count[_ptr]--; } _ptr = src._ptr; } bool unique() { if (count.find(_ptr)
== count.end()||count[_ptr]==1)// The order cannot be changed { return true; } return false; } T*
release() { T* tmp = _ptr; if (unique()) { _count.erase(_ptr); } else { _count[
_ptr]--; } _ptr = NULL; return tmp; } void reset() { if (unique()) { _count.
erase(_ptr); delete _ptr; } else { _count[_ptr]--; } _ptr = NULL; } T& operator*
() { return *_ptr; } T* operator->()// Arrow call , Is a second call { return _ptr; } operator bool(
) { return _ptr!=NULL; } private: static map<T*, int>* _count; T* _ptr; };
<> Smart pointer with reference count weak_ptr—— Weak intelligent pointer

* Cannot be used directly , Cannot dereference ;
* If you want to use it, you must first convert it to a strong smart pointer , use lock() Return strong smart pointer ;
* Weak smart pointers do not occupy the reference count ;
* Weak smart pointers can only be constructed from strong smart pointers ;
weak_ptr References to resources do not change the reference count of resources , Usually as an observer , Used to determine whether the resource exists , And make corresponding operations according to different situations .

For example, use weak_ptr Weak reference to resources , When called weak_ptr of lock() Method time , If return nullptr
, Then the resource no longer exists , Abort continue operation on resource . otherwise , Will return a shared_ptr object , You can continue to operate on resources .

Once the last point to the object shared_ptr Destroyed , The object will be released . Even if there is weak_ptr Point to object , Or will the object be released .

class A { public: A() { cout << "A()" << endl; } ~A() { cout << "~A()" << endl;
} weak_ptr<B> _ptr_b; }; class B { public: B() { cout << "B()" << endl; } ~B() {
cout<< "~B()" << endl; } weak_ptr<A> _ptr_a; }; void fun() { shared_ptr<A> a_p(
newA()); shared_ptr<B> b_p(new B()); shared_ptr<int> p(new int(10));
// Constructing weak smart pointer with strong smart pointer weak_ptr<int> w_p(p); cout << *p << endl; cout << *(w_p.lock())
<< endl;//lock Return strong smart pointer shared_ptr<int> tmp = w_p.lock(); a_p->_ptr_b = b_p;
// Failure to destruct b_p->_ptr_a = a_p; }
<> Simulation Implementation mweak_ptr
#ifndef MWEAK_PTR_H #define MWEAK_PTR_H #include"mshared_ptr.h" template<
typename T> class Mweak_ptr { public: Mweak_ptr(Mshared_ptr& s_ptr) { _s_ptr =
s_ptr.get(); Mshared_ptr<T>::_count.insert(make_pair(_ptr, 1)); // Plus friends can visit }
Mshared_ptr<T> lock() { if (Mshared_ptr<T>::_count.find(_s_ptr) != Mshared_ptr<T
>::_count.end()) { return Mshared_ptr<T>(_s_ptr); } return Mshared_ptr<T>(); }
private: T* _s_ptr; }; #endif

Technology
©2019-2020 Toolsou All rights reserved,
C++ of string of compare usage Python Study notes ( one )evo Tool usage problems ——Degenerate covariance rank, Umeyama alignment is not possibleRISC-V_GD32VF103-TIMER0 timer interrupt java Array subscript variable _Java Basic grammar : array be based on stm32 Control four-wheel trolley motor drive ( one ) be based on redis Design of liking function Software engineering career planning mysql Query random data by conditions _MySQL Random query of several qualified records centos7 install RabbitMq