智能指针
1. 概念
1.1. 普通指针的遗憾
- 可能存在忘记释放内存
- 可能二次释放内存
-
1.2. 智能指针的定义
智能指针(smart pointer)是个类模板,头文件为
- 只管new内存,不用考虑内存的管理
- 在C++11中有三种智能指针
- unique_ptr
- shared_ptr
- weak_ptr
- unique_ptr
所有智能指针都具有的方法
独占拥有式智能指针,只有一个unique_ptr指向某个对象,unique_ptr对象在自身生存周期结束时自动销毁所指对象。
2.2. 方法接口
无参构造方法
`unique_ptr<A> ptr;`
单参构造方法
`unique_ptr<A> uptr(new A);`
不支持拷贝构造
`unique_ptr<A> up1(up); //error`
不支持赋值=
`up1 = up; //error`
2.3. 示例代码
```cpp
include
include
using namespace std;
class A{ public: ~A(){ cout << “~A()” << endl; } A(){ cout << “A()” << endl; } void test(){ cout << “test()” << endl; } };
int main(){ A* p = new A; p->test(); //delete p;
cout << "-----------" << endl;unique_ptr<A> uptr(new A);uptr->test();(*uptr).test();unique_ptr<A> uptr1;//uptr1 = uptr; // errorreturn 0;
}
---<a name="NiWdL"></a># 3. shared_ptr<a name="kwcRD"></a>## 3.1. 概念- 共享拥有式智能指针,多个智能指针可以指向一个对象。<a name="lP1yj"></a>## 3.2. 方法接口- 无参构造方法`shared_ptr<A> sptr;`- 单参构造方法`shared_ptr<A> sptr(new A);`- 拷贝构造`shared_pstr<A> sptr1(sptr);`- 赋值=`shared_ptr<A> sptr1; sptr1 = sptr;`- 使用计数:`.use_count() //返回所指对象的使用计数`<a name="W9QWe"></a>## 3.3. shared_ptr的实现原理- 内部使用一个计数器,统计指向某个对象的智能指针个数。- 当计数器为0时,智能指针delete所指对象- 智能指针初始化时,计数器置1- 智能指针拷贝构造时,计数器加1- 智能指针赋值时,计数器加1- 智能指针析构时,计数器减1<a name="g6mHy"></a>## 3.4. 示例代码```cpp#include <iostream>#include <memory>using namespace std;class A{public:~A(){cout << "~A()" << endl;}A(){cout << "A()" << endl;}void test(){cout << "test()" << endl;}};int main(){shared_ptr<A> sptr(new A);sptr->test();cout << "use_count : " << sptr.use_count() << endl;shared_ptr<A> sptr1(sptr);sptr1->test();cout << "use_count : " << sptr.use_count() << endl;shared_ptr<A> sptr2;sptr2 = sptr;sptr2->test();cout << "sptr.use_count : " << sptr.use_count() << endl;shared_ptr<A> sptr3(new A); // sptr3.use_count == 1cout << "sptr3.use_count : " << sptr3.use_count() << endl;return 0;}
4. weak_ptr
4.1. 概念(解决shared_ptr循环指向问题)


- weak_ptr称为弱指针,协助shared_ptr工作,解决shared_ptr的循环指向问题
- weak_ptr总是指向一个用shared_ptr管理的对象,共享但不拥有对象
4.2. 示例代码
```cppinclude
include
using namespace std;
class B; // 前置声明
class A{ public: //shared_ptr msptrb; weak_ptr msptrb; // 采用上面屏蔽的做法,会导致循环指向问题 ~A(){ cout << “~A()” << endl; } A(){ cout << “A()” << endl; } void test(){ cout << “A : test()” << endl; } };
class B{ public: //shared_ptr msptra; weak_ptr msptra; // 采用上面屏蔽的做法,会导致循环指向问题 ~B(){ cout << “~B()” << endl; } B(){ cout << “B()” << endl; } void test(){ cout << “B : test()” << endl; } }; int main(){ shared_ptr sptra(new A); shared_ptr sptrb(new B);
sptra->msptrb = sptrb;sptrb->msptra = sptra;cout << "sptra.use_count : " << sptra.use_count() << endl;cout << "sptrb.use_count : " << sptrb.use_count() << endl;return 0;
} ```
