unique_ptr使用详解(介绍,场景,方法,实例)
1.什么是uniqueptr
uniqueptr是智能指针的一种,主要用于C++的内存申请和释放,因为C++在申请内存后,要手动进行delete,这样就会出现有时候忘记delete,或者return,break,异常等原因没有执行到delete,如下面的代码所示,new了一个A的对象,要时刻注意delete销毁对象,而且如果是new了多个对象,需要同时注意什么时候销毁什么对象,return,break,异常等情况都要考虑,所以这就给开发造成很大的困扰。不知道什么时候delete内存,所以引入uniqueptr指针,当指针销毁不时,自动删除指针指向的内存。unique_ptr的特点是只允许一个指针指向这块内存,unique_ptr赋值操作是不允许的,例如uniqueptr1=uniqueptr2;是不允许的,只能通过转移,uniqueptr1=move(uniqueptr2);将uniqueptr2指向的内存转移给uniqueptr1。:可以从一个函数中返回一个unique_ptr;
#include <memory> #include<iostream> using namespace std; class A {}; int main() { A* ptrA = new A; try {
if()
{
delete ptrA;
return -1;
}
//... //... //... //... //... } catch (...) { delete ptrA; //1 throw; } delete ptrA; //2 return 0; }
2.使用方法
上面的代码如果用uniqueptr就方便很多,只要申请unique_ptr指针指向内存,ptrA的作用域结束后销毁,会自动销毁ptrA 指向的内存;不用再去关注什么时候销毁内存;
#include <memory> #include<iostream> using namespace std; class A {}; int main() { unique_ptr<A> ptrA = make_unique<A>();
//unique_ptr<A> ptrA(new A);//第二种方式 try { if() { //..... return -1; } //... //... //... //... //... } catch (...) { throw; } return 0; }
3.详细介绍
#include "stdafx.h" #include <iostream> using namespace std; #include <string> #include <memory> int main() { unique_ptr<int> uptr1 = make_unique<int>();//新建第一个对象 //unique_ptr<int> uptr2 = uptr1;//错误,唯一指向,不能赋值给其他指针 unique_ptr<int> uptr2 = move(uptr1);//将指针uptr1指向的内存转移给uptr2,uptr1变为空 unique_ptr<int> uptr3= make_unique<int>();//新建第二个对象 int* p4 = uptr3.get();//返回指针uptr3指向的对象,可以修改对象的值,但是不能执行delete p4;否则uptr3销毁时释放内存会报错; *p4 = 8;//修改内存保存的值 //delete p4;//会报错如下图所示,这里销毁一次,uptr3又销毁一次; uptr3.release();//释放uptr3指向内存,但是不销毁内存; unique_ptr<int> uptr4(new int);//新建第三个对象 uptr4.reset();//清空uptr4指向,并且销毁指向内存; unique_ptr<int> uptr5(new int);//新建第四个对象; uptr5.reset(new int);//新建第五个对象,uptr5指向第五个对象,并销毁第四个对象内存; unique_ptr<int> uptr6; uptr6.reset(new int);//新建第六个对象,uptr6指向第六个对象
return 0; }
使用unique_ptr需要包含头文件:
#include<memory>
创建和初始化
#include <iostream> #include <memory> using namespace std; int mian() { unique_ptr<int> p; // 可以指向int对象的一个空智能指针 unique_ptr<int> p(new int(105)); // p指向一个值为105的int对象 auto p(new int(105)); // 不能简写为auto,这里auto推断出是普通指针
unique_ptr<int> p = make_unique<int>(100);//C14才出现make_unique
auto p = make_unique<int>(200);
}
但是,release函数会取消unuque_ptr对内存的管理,但是不会删除内存,需要手动删除release取消管理的内存,如果我们不用另一个智能指针来保存release() 返回的指针,我们的程序就要负责资源的释放,否则就会有内存泄漏
#include <iostream> #include <memory> using namespace std; int mian() { unique_ptr<string> p1(new string("hello")); // release()返回p1当前保存的指针,并将p1置为空。p2被初始化为p1原来保存的指针,即将所有权从p1转移给p2 unique_ptr<string> p2(p1.release()); }
reset取消内存管理,同时删除内存
#include <iostream> #include <memory> using namespace std; int mian() { unique_ptr<string> p1(new string("hello")); p1.reset();//删除内存 }
reset带参数,则是指向新内存,删除旧内存
#include <iostream> #include <memory> using namespace std; int mian() { unique_ptr<string> p1(new string("hello")); p1.reset(new string("world")); }
get返回智能指针指向的内存指针,依赖修改内存存储的值
#include <iostream> #include <memory> using namespace std; int mian() { unique_ptr<string> up(new string("hello")); string* p = up.get(); *p = "world"; }
自定义删除器,删除器会在 unique_ptr 被销毁时调用,可以是函数指针、函数对象或lambda表达式*。通常,使用lambda表达式来定义自定义删除器是比较方便的。
自定义删除器的应用场景:
对于需要特殊处理的资源,如大内存块、缓存等,自定义删除器可以提供更高效的内存管理方式。
对于特定资源,如文件句柄、数据库连接等,使用自定义删除器可以确保资源的正确释放和管理。
通过使用自定义删除器,std::unique_ptr能够在释放资源时执行特定的清理操作,从而帮助节省内存并提升性能
void customDeleter(int* ptr) { // 自定义删除逻辑 delete ptr; } std::unique_ptr<int, decltype(&customDeleter)> ptr(new int(5), customDeleter);
#include <iostream> #include <memory> using namespace std; void customDeleter(string* ptr) { delete ptr; ptr = nullptr; } int main() { // 使用using using cus_del = void(*)(string*); unique_ptr<string, cus_del> uni_ptr(new string("hello"),customDeleter); // 使用 lambda auto my_del = [](string* ptr)->{ delete ptr; ptr = nullptr; } unique_ptr<string, decltype(my_del)> uni_ptr(new string("hello"),my_del ); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix