## 今天学了什么
今天学习C++11的智能指针:共享智能指针(shared_ptr)、独占智能指针(unique_ptr)、弱引用智能指针(weak_ptr)。
头文件<memory>
## shared_ptr
①初始化
Ⅰ.通过构造函数进行初始化:
shared_ptr<int> ptr1(new int);
Ⅱ.通过拷贝构造初始化:
shared_ptr<int> ptr2 = ptr1;
Ⅲ.移动构造:
shared_ptr<int> ptr3 = move(ptr2);
Ⅳ.make_shared初始化
shared_ptr<int> ptr4 = make_shared<int>(1);
Ⅴ.reset
ptr3.reset(new int);
②共享智能指针使用
Ⅰ.获取原始地址
shared_ptr<Test> ptr(new Test);
Test *t = ptr.get();
t->ptintInfo();
Ⅱ.通过智能指针直接对对象进行操作
ptr->ptintInfo();
③删除器
对于特殊情况/非堆资源的内存释放,默认删除器(default_delete())无法释放,需要手动写删除器。
例:当new了一个数组,默认删除器无法全部释放,手动写如下:
- shared_ptr<Test> ptr3(new Test[5], [](Test* t) { delete[] t; }); //5
- shared_ptr<Test> ptr5(new Test[5], default_delete<Test[]>()); //1
- shared_ptr< Test[]> ptr4(new Test[5]); //5 C++11以后支持
④使用 shared_ptr 注意事项
Ⅰ.不能使用一个原始地址初始化多个智能指针
Test* t = new Test(5);
shared_ptr< Test> ptr(t);
shared_ptr< Test> ptr2=ptr; ✔ // shared_ptr< Test> ptr2(t); ✘
Ⅱ.函数不能返回管理了this的智能指针对象
shared_ptr< Test> ptr3;
ptr3=ptr2->GetSharedPtr();//shared_ptr<Test> GetSharedPtr(){return shared_ptr<Test>(this);}
解决方法:
struct Test : public enable_shared_from_this<Test>{ … //返回管理了this的共享指针 shared_ptr<Test> GetSharedPtr() { return shared_from_this(); }Ⅲ.不能循环引用
将shared_ptr<TB> bptr; 改为 weak_ptr<TB> bptr; 以解决循环引用无法析构问题。
class TB; class TA { public: weak_ptr<TB> bptr; ~TA() { cout << "TA 的析构" << endl; } }; class TB { public: shared_ptr<TA> aptr; ~TB() { cout << "TB 的析构" << endl; } };shared_ptr<TA> a(new TA);
shared_ptr<TB> b(new TB);a->bptr = b;
b->aptr = a;
## unique_ptr
①初始化
Ⅰ.通过构造函数进行初始化:
unique_ptr<int> ptr(new int);
Ⅱ.移动构造:
unique_ptr<int> ptr2=move(ptr);
Ⅲ.reset
ptr2.reset(new int);
*注:unique_ptr不能通过拷贝构造初始化,原因:一块内存,同一时间只能有1个unique_ptr持有它,不能共享。
②独占智能指针使用
Ⅰ.获取原始地址
unique_ptr< Test> ptr(new Test);
Test* t = ptr.get();
t->func();
Ⅱ.通过智能指针直接对对象进行操作
ptr->func();
③删除器
三种写法:
using ptrFunc = void(*)(Test*);
unique_ptr< Test,ptrFunc> ptr3(new Test[1], [](Test* t) {
delete[] t;
}); //[]无捕获,没有成员变量,编译器额外给他转成普通函数指针
unique_ptr< Test,function<void(Test*)>> ptr4(new Test[1], [=](Test* t) {
delete[] t;
}); //[=]有捕获,不能转,必须用function包装
unique_ptr<Test[]> ptr5(new Test[1]); //特点:管理数组类型的地址能自动释放
## weak_ptr
①初始化
通过共享智能指针实例化:
Ⅰ.
shared_ptr<int> sptr(new int);
weak_ptr<int> wptr2 = sptr;Ⅱ.
weak_ptr<int> wptr3(wptr2);
Ⅲ.
weak_ptr<int> wptr;
weak_ptr<int> wptr4;wptr = wptr2;
wptr4=sptr;
②常用方法
Ⅰ.use_count()(返回所监测资源的引用计数);
Ⅱ.expired()(判断观测的资源是否已经被释放);
if (wptr.expired())
{
cout << "已经释放" << endl;
}
else
{
cout << "weak_ptr 没有释放" << endl;
}
Ⅲ.lock()(获取管理监测对象资源的shared_ptr对象);
shared_ptr<int> sptr2 = wptr2.lock();
* 注:weak_ptr只是监测指针,不能直接解引用,没有 * 、->,不能直接访问资源,想访问只能调用 lock() 拿到shared_ptr。
③reset()重置