1 unique_ptr的release操作和reset操作
unique_ptr会独占所管理的指针,一般不能被拷贝或赋值。
部分操作与shared_ptr类似,但指定删除器需要指定删除器的类型:
void freeInt(int* p)
{
std::cout << "delete p : " << *p << std::endl;
delete p;
}
int main()
{
{
// unique_ptr在指定删除器的时候 需要指定删除函数的类型(函数指针的类型)
// 在decltype后边加个* 表示要使用该类型的指针的类型
std::unique_ptr<int, decltype(freeInt)*> up(new int(10), freeInt);
}
}
reset与relase操作:
release会切断unique_ptr与指针的联系,reset会让unique_ptr执行释放操作
{
// release操作会让unique_ptr放弃对指针的管理 且不会执行释放操作 并返回这个普通指针 即切断和原来普通指针的联系
std::unique_ptr<int, decltype(freeInt)*> up(new int(100), freeInt);
int* p = up.release(); // 注意一定要保存release函数的返回值 否则会丢失该指针
if (!up) { // 与shared_ptr一样 重载了operator bool 用于判断当前有没有管理指针
std::cout << "Empty up" << std::endl;
}
std::cout << *p << std::endl; // 返回的普通指针依然可以正常使用
}
{
// reset操作会让unique_ptr放弃对指针的管理 并对指针执行释放操作
std::unique_ptr<int, decltype(freeInt)*> up(new int(1000), freeInt);
up.reset();
if (!up) {
std::cout << "Empty up" << std::endl;
}
}
2 某些情况下,unique_ptr也是可以被拷贝的
可以拷贝或赋值一个将要被销毁的unique_ptr(右值?) 例如可以作为函数返回值来被拷贝
#include <iostream>
#include <memory>
#include <string>
#include <stdio.h>
void deleteFun(FILE* file)
{
if (file) {
fclose(file);
file = nullptr;
std::cout << "Close file" << std::endl;
}
}
std::unique_ptr<FILE, decltype(deleteFun)*> getOpenFile(const char* path)
{
FILE* file = fopen("./a.txt", "w");
std::unique_ptr<FILE, decltype(deleteFun)*> filePtr(file, deleteFun); // 使用unique_ptr封装一个FILE* 并指定删除器(替代delete操作)
return filePtr;
}
int main()
{
// getOpenFile返回了一个unique_ptr 执行了某种拷贝 将管理的指针给了unique_ptr_file
// 在getOpenFile返回时 其中的filePtr即使作用域结束也并执行删除器 代码运行后只打印了一次"Close file"
// 这是一种特殊的”拷贝“
auto unique_ptr_file = getOpenFile("./a.txt");
return 0;
}
3 如果试图为unique_ptr进行拷贝或赋值操作,编译器会报错
“std::unique_ptr<int,void (__cdecl *)(int *)>::unique_ptr(const std::unique_ptr<int,void (__cdecl *)(int *)> &)”: 尝试引用已删除的函数
因为标准库将拷贝构造函数和赋值函数声明为delete的
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;