文章目录
前言
智能指针本质上来讲是一个存储指向堆内存指针的类,目的就是帮助我们管理内存,一旦使用了智能指针就就尽量使用new产生的指针,因为智能指针只维护同类型指针的引用计数,混用很容易造成内存重复释放的问题
unique_ptr
std::unique_ptr是一种独占所有权的智能指针,它确保指向的对象只有一个所有者,并负责在其生命周期结束时自动释放对象,一块内存只能由一个unique_ptr进行管理,如果有其它的unique想要管理,就只能用move进行资源转移,它的内部计数不能超过1
使用场景:适用于管理单个所有者的对象,通常用于替代原始指针和new/delete操作。
使用方法:
- 初始化
#include <memory>
int main() {
std::unique_ptr<int> ptr(new int(42));
// 使用ptr
*ptr = 10;
// ptr的生命周期结束时,会自动释放动态分配的内存
return 0;
}
unique_ptr不允许复制,只能用move来移动所有权,如:
unique_ptr<int> ptr1 = move(ptr);
- 数组
std::unique_ptr<int[]> arr(new int[size]); // 使用智能指针管理动态数组
shared_ptr
std::shared_ptr是一种共享所有权的智能指针,它允许多个std::shared_ptr指向同一个内存,通过引用计数来管理对象的生命周期,每多一个指针指向这个对象,它内部的引用计数就会加1,析构一个就减一,当引用计数为0的时候就调用它的析构函数释放这块内存
1.使用场景:适用于多个所有者的场景,允许对象被多个地方共享并且在最后一个所有者释放对象时销毁
2.使用方法:
- 初始化
#include <memory>
int main() {
//std::shared_ptr<int> ptr1 = new int(42);//错误,不允许用原始指针进行赋值
std::shared_ptr<int> ptr1 = std::make_shared<int>(42);//最高效的一种初始化方法
std::shared_ptr<int> ptr2 = ptr1; // 多个shared_ptr指向同一对象
std::shared_ptr<int> ptr3(new int(1));//利用构造函数初始化
// 使用ptr1和ptr2
*ptr1 = 10;
// 当最后一个shared_ptr被销毁时,对象会被释放
return 0;
}
- 管理动态数组
#include <memory>
int main() {
int size = 10;
std::unique_ptr<int[]> arr(new int[size]); // 使用智能指针管理动态数组
// 对数组进行操作
for (int i = 0; i < size; ++i) {
arr[i] = i;
}
// 不需要手动释放内存,当 unique_ptr 被销毁时,动态数组内存会自动释放
return 0;
}
3.使用注意事项:
- 不要用一个原始指针初始化多个shared_ptr
int* ptr = new int;
shared_ptr<int> p1(ptr);
shared_ptr<int> p2(ptr);//错误,应该用p1初始化p2
- 避免循环引用
#include <memory>
class B; // 前向声明类 B
class A {
public:
std::shared_ptr<B> b_ptr; // A 持有对 B 的 shared_ptr
};
class B {
public:
std::shared_ptr<A> a_ptr; // B 持有对 A 的 shared_ptr
};
int main() {
std::shared_ptr<A> a(new A());
std::shared_ptr<B> b(new B());
// 循环引用
a->b_ptr = b;
b->a_ptr = a;
return 0;
}
循环引用导致a和b的引用计数为2,由于释放一个 shared_ptr 时,如果其引用计数不为 1(即存在其他指针也指向同一块内存),则仅减少引用计数,而不会立即销毁管理的对象,因此离开作用域后引用计数减为1,内存泄漏,解决办法是把a和b的任意成员变量改为weak_ptr,如:
std::weak_ptr<A> a_ptr; // B 持有对 A 的 shared_ptr
为什么引用计数开始的时候无法减为0,而用了weak_ptr就能解决问题了,这是因为weak_ptr不会增加引用计数,我画一个图来说明一下
weak_ptr
std::weak_ptr是一种弱引用智能指针,它允许观察std::shared_ptr指向的对象,但不会增加引用计数,也不会阻止对象的销毁。
使用场景:通常用于解决std::shared_ptr循环引用导致的内存泄漏问题,或者在需要观察对象但不需要拥有所有权的情况下使用。
使用方法:
- 用use_count获取当前观测的资源数
shared_ptr<int> sp(new int(10));
weak_ptr<int> wp(sp);
cout<<wp.use_count()<<endl;
- 用expired判断所观测的资源是否已经释放
std::shared_ptr<A> a_ptr; // B 持有对 A 的 shared_ptr
weak_ptr<int> wp = sp;
if(wp.expired()){
cout<<"释放过了已经"<<end;
}
- 用lock获取所监视的shared_ptr
#include <memory>
int main() {
std::shared_ptr<int> ptr = std::make_shared<int>(42);
std::weak_ptr<int> weakPtr = ptr;
// 使用weakPtr
if (auto sharedPtr = weakPtr.lock()) {
// 如果对象未被释放,则获取shared_ptr并使用
*sharedPtr = 10;
} else {
// 对象已经被释放
}
return 0;
}
标签:std,int,智能,详解,shared,unique,ptr,指针
From: https://blog.csdn.net/m0_56049283/article/details/136972463