Advanced C ++ smart pointer ----

1 Basic Concepts

1.1 Pointer hazards:

指针未初始化
野指针:
内存泄漏(申请动态内存 未释放)

1.2 Classification

Here Insert Picture Description

1.3 essence

Packaging pointer to the class object member , and the destructor remove pointer memory.

1.4 Different

name different
auto_ptr Immediately deleted.
unique_ptr Immediately deleted.
scoped_ptr Immediately deleted.
shared_ptr Count is 0 deleted.
weak_pt Do not delete

2auto_ptr

2.1 Role

Dynamic allocation of objects within the scope of the automatic release

2.2 Basic Types

int *p=new int(10);
	cout<<*p<<endl;//这样会导致内存泻露 通过valgrind ./a.out 就可以看出申请一个 释放0个 泄露4个字节
	//智能指针
	miniSTL::auto_ptr<int> ap(p);
	cout<<*ap<<endl;//ap等同与p    通过valgrind ./a.out 就可以看出申请一个 释放1个 无泄露

2.3 class type

Test *t=new Test;
	t->Func();//通过valgrind ./a.out 就可以看出申请一个 释放0个 泄露1个字节
	miniSTL::auto_ptr<Test> apt(t);
	t->Func();//通过valgrind ./a.out 就可以看出申请一个 释放1个 无泄露

2.4 Defects

2.4.1 two auto_ptr can not have the same object

int *p=new int(10);
	cout<<*p<<endl;
	 auto_ptr<int> ap1(p);
	const auto_ptr<int> ap2(p);//erro :double free 导致内存泄露
	cout<<*ap1<<" ----"<<endl;
	

2.4.2auto_ptr can not manage an array of pointers

#include <memory>
using namespace std;
int main(){
    int*pa=new int[10];
    auto_ptr<int>ap(pa);
}

After 2.4.3auto_ptr be copied or assigned, managed to lose the original pointer. This condition is called pointer ownership transfer.

Here Insert Picture Description

Assignment

auto_ptr<int> ap3=ap1;
	cout<<*ap1<<endl;//段错误(吐核) 
			//错误原因 是因为ap1 把指针给了ap3 而自己为了避免2次释放 所以给自己赋值为空 
	cout<<*ap3<<endl;//正常

copy

void Func(auto_ptr<int> ap){
    cout << *ap << endl;
}
int main(){
    int*p = new int(10);
    auto_ptr<int> ap(p);
    cout<< *ap <<endl;
    Func(ap);
    //段错误
    cout<< *ap <<endl;
}

2.4.4auto_ptr container can not serve as an object, as the elements of STL containers often supports copy, the assignment operation.

在这里插入代码片

3unique_ptr (instead of the auto_ptr)

3.1 Features

Do not let the pointer assignment, do not copy the specific implementation function to its privatization

template<class T>
class unique_ptr{
T* m_p;
private:
	unique_ptr(const unique_ptr& a);
	unique_ptr& operator=(const unique_ptr& a);
};

4scoped_ptr

4.1 Role

And unique_ptr similar to the use of this scope can not be copied and assigned.

The difference between 4.2 and unique_ptr

The copy constructor function disables assignment operator overloading

class auto_ptr{
T * m_p;
public:
	auto_ptr(T* p):m_p(p){}
	auto_ptr(const auto_ptr& p):m_p(p.m_p)=delete
	
	auto_ptr& operator=(const auto_ptr& a)=delete
}

5shared_ptr

5.1 Advantages

//使用shared_ptr可以可以解决智能指针拷贝和赋值问题
	//写时copy技术
	shared_ptr<Test> sp(new Test(10));
	shared_ptr<Test> sp2(sp);
	cout<<*sp<<endl;
	cout<<*sp2<<endl;

Nature: sp and sp2 shared an address but will not release 2

5.2 Testing

#include<iostream>
#include<memory>  
using namespace std;
class Test{
int m_n;
public:
	Test(int n):m_n(n){
		cout<<"construct"<<m_n<<endl;
	}
	Test(){
		cout<<"construct"<<m_n<<endl;
	}

	~Test(){
		cout<<"destructor"<<m_n<<endl;
	}
	void Func()const{
		cout<<"func"<<endl;
	}
	friend ostream& operator<<(ostream& os,const Test& t){
		os<<"Test ("<<t.m_n<<")";
		return os;
	}
};

void Func(shared_ptr<Test> p){
	cout<<p<<endl;

}
int main(){

	shared_ptr<Test> sp(new Test(10));
	shared_ptr<Test> sp2(sp);
	cout<<*sp<<endl;
	cout<<*sp2<<endl;
	Func(sp);
	cout<<(*sp)<<endl;


}

The results of the conducted a constructor and destructor prove that no deep copy

construct 10
Test(10)
Test(10)
Test(10)
Test(10)
destructor

5.3 Question: circular reference problem

#include<iostream>
#include<memory>
using namespace std;
class B;
class A{
public: 
	A(){cout<<"A construct"<<endl;}
	~A(){cout<<"A destruct"<<endl;}
	//第一次情况
	//shared_ptr<B>m_b;
	//第二次请况 改正情况
	weak_ptr<B> m_b;

};
class B{
public:
	B(){cout<<"B construct"<<endl;}
	~B(){cout<<"B destruct"<<endl;}
	shared_ptr<A> m_a;

};
int main(){
	shared_ptr<A> pa(new A);
	shared_ptr<B> pb(new B);	
	
	pa->m_b=pb;
	pb->m_a=pa;//两个赋值之间只要去掉一次赋值 既AB就都可以析构
	/*第一次结果
	[root@foundation66 c++]# ./a.out 
	A construct
	B construct
	导致循环引用问题的原因是:如果A想要析构 那么首先的析构A的成员m_b 而mb如果要析构 那末又的先析构m_a所以出现了循环的请况
	*/
	//解决方式weak_ptr
	/*[root@foundation66 c++]# g++  8_4shared_ptr_problem.cpp -std=c++11
 	* [root@foundation66 c++]# ./a.out 
 	* A construct
 	* B construct
 	* B destruct
 	* A destruct
 	*/

}

6weak_ptr

Shared_ptr circular reference problem solving

6.1 Benefits

1 break recursive dependencies
2 uses a shared resource, but not ownership, not to add a reference count
3 to avoid dangling pointers.

7 summary

Here Insert Picture Description

Published 27 original articles · won praise 4 · Views 1338

Guess you like

Origin blog.csdn.net/weixin_45639955/article/details/104295196