1. shared_ptr
两智能指针默认底层都是用new申请内存,delete释放内存
包含头文件 #include <memory>
作用域 std::shared_ptr
初始化:
shared_ptr<int> sp { new int(100) }; //<>里可以是自定义类型
shared_ptr<int> sp { make_shared<int>(100) };
shared_ptr<int> sp = make_shared<int>(100); //推荐make_shared
复制:
shared_ptr<int> sp2 = sp; //计数+1
计数: (引入计数功能,开销增加,性能低于裸指针)
sp.use_count(); //可查看当前有多少共享指针指向同一块内存
重置:
sp.reset(); // sp指向nullptr,sp计数为0(只能用其它智能指针计数,其它智能指针计数-1)
// 或者函数结束,智能指针自动销毁
sp.reset(new int(200)) //可以将sp指向新地址,原地址计数-1,新地址计数+1
转裸指针: (一般不建议共享指针与裸指针共用内存)
int *ptr = sp.get(); //有时候函数参数不接收智能指针,只接受普通指针
//裸指针不参与智能指针计数,当该内存计数为0时,裸指针依然指向该内存,只是内存里的数据清空了
//<>若为自定义类型,智能指针计数为0后,裸指针依然能调用类成员函数接口
2. unique_ptr
零开销!推荐使用!
包含头文件 #include <memory>
作用域 std::unique_ptr
初始化:
unique_ptr<int> up { new int(100) }; //<>里可以是自定义类型
unique_ptr<int> up { make_unique<int>(100) };
auto up = make_unique<int>(100); //推荐make_unique
没有复制,没有计数
但可以传递:
int * ptr = new int(10);
unique_ptr<int> up(ptr); //独享指针可指向指定 裸指针 内存
unique_ptr<int> up2(up.release()); //与下文解绑连用,将up指向空,将up2指向该内存。(独享指针传递内存)
unique_ptr<int> up2 = move(up); //与上一条语句效果一样,独享指针传递内存
重置:
up.reset(); // up指向nullptr // 或者函数结束,智能指针自动销毁
up = nullptr; //作用类似,也会释放内存,并将up指向nullptr
up.reset(new int(200)) //可以将up指向新地址
转裸指针:
int *ptr = up.get();
解绑:
//up.release()返回裸指针
int *ptr2 = up.release(); //将独享指针up指向nullptr,内存由裸指针ptr2接管
delete ptr2; //记得手动释放内存
ptr2 = nullptr;
函数传参:
void func(unique_ptr<int>& _up){} //我们一般传原独享指针的引用,因为独享指针不能复制
//或者
void func(unique_ptr<int> _up){} //不用引用
func(move(up)); //但传参时得用move,移交内存,up指向nullptr
函数返回值:
return up; //可直接返回up,无需返回move(up)(这样返回也可以),系统自动判断不会进行复制操作,自动进行move操作