C++ shared_ptr
shared_ptr
shared_ptr 是C++11提供的一种智能指针类,它足够智能,可以在任何地方都不使用时自动删除相关指针,从而帮助彻底消除内存泄漏和悬空指针的问题。
shared_ptr使用引用计数,每个shared_ptr的拷贝都指向相同的内存,在最后一个shared_ptr析构的时候,内存才会释放。
(1)初始化
可以通过构造函数、std::make_shared< T >辅助函数和reset方法来初始化shared_ptr:
- 使用原始指针建立智能指针
- std::make_shared 一次性为int对象和用于引用计数的数据都分配了内存,而new操作符只是为int分配了内存。
- reset:
不带参数的reset(): 可以将引用计数减少1,如果引用计数变为0,则删除指针。
带参数的reset():在这种情况下,它将在内部指向新指针,同时改变引用计数。
还可以使用nullptr重置。
shared_ptr还重载了bool类型操作符来判断智能指针是否为空。
(2)获取原始指针
通过get方法返回原始指针。
#include <iostream>
#include <functional>
#include <memory>
void cout_p(std::shared_ptr<int> a){
std::cout<<*a<<std::endl;
}
int main(void)
{
std::shared_ptr<int> p1(new int (10));
std::shared_ptr<int> p2 = std::make_shared<int>();
cout_p(p1);
*p2 = 200;
cout_p(p2);
std::shared_ptr<int> p3 = p1;
std::cout<<p3.use_count()<<std::endl; //打印引用次数
int* p = p1.get() //返回原始指针
}
(3)指定删除器
智能指针初始化可以指定删除器:
删除器可以是lambda表达式
注意:使用shared_ptr管理动态数组时,需要指定删除器,因为std::shared_ptr的默认删除器不支持数组对象
void mydel(int *p){
delete p;
}
std::shared_ptr<int> p1(new int (10), mydel);
std::shared_ptr<int> p2(new int (10), [](int *p){delete p;}); // lambda表达式作为删除器
std::shared_ptr<int> p3(new int[10], [](int *p){delete[] p}); // 数组的删除器delete[]
使用shared_ptr需要注意的问题:
- 不要用一个原始指针初始化多个shared_ptr,会报错。
- 不要在函数实参中创建shared_ptr,有内存泄漏的风险。
function (shared_ptr< int >(new int), g());
因为C++的函数参数的计算顺序在不同的编译器中的调用约定可能是不一样的。可能先调用了new int,然后调用g(),如果这时g()发生异常,而shared_ptr还没创建,则发生内存泄漏。 - 不要将this指针作为shared_ptr返回,可能导致重复析构
- 不要重复引用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!