智能指针
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; // error
return 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 == 1
cout << "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;
} ```