1.智能指针简介
2.unique_ptr 独占式智能指针
3.shared_ptr 共享式智能指针
4.weak_ptr 弱引用智能指针
1.智能指针简介
智能指针在C++标准库(memory头文件)中, 核心目的是"自动管理动态分配的内存", 避免忘记手动调用delete, 造成的内存
泄露问题; 智能指针会在自身生命周期结束后(如: 超出作用域)自动调用delete释放关联的内存
2.unique_ptr 独占式智能指针
unique_ptr是独占所有权的智能指针, "同一时间, 只能有一个unique_ptr指向该对象", 不支持拷贝, 仅支持移动(move)
#include <iostream>
#include <memory>
using namespace std;
int main() {
unique_ptr<int> up1(new int(10));
cout << *up1 << endl;
auto up2 = make_unique<string>("hello");
cout << *up2 << endl;
unique_ptr<int> up3 = move(up1);
if (up1 == nullptr) {
cout << "up1已失去对象所有权" << endl;
}
cout << *up3 << endl;
up3.reset();
return 0;
}
当你直接写 unique_ptr<int> up1(new int(10)) 时,代码的执行分为两步:
执行 new int(10):动态分配内存,创建一个 int 对象;
调用 unique_ptr 的构造函数:接管第一步分配的内存。
问题出在:这两步之间可能抛出异常,导致第一步分配的内存 “无人接管”,最终内存泄漏
#include <iostream>
#include <memory>
using namespace std;
void func(unique_ptr<int> ptr, int value) {
}
int get_value() {
throw runtime_error("获取值失败");
return 10;
}
int main() {
try {
func(unique_ptr<int>(new int(10)), get_value());
} catch (const exception& e) {
cout << "异常:" << e.what() << endl;
}
return 0;
}
3.shared_ptr 共享式智能指针
shared_ptr是共享所有权的智能指针, 多个shared_ptr可以指向同一个对象, 内部通过引用计数管理内存; 每拷贝一个指针
引用计数+1; 每销毁一个指针, 计数-1; 当计数为0时, 自动释放内存
#include <iostream>
#include <memory>
using namespace std;
int main() {
shared_ptr<int> sp1 = make_shared<int>(20);
cout << "引用计数:" << sp1.use_count() << endl;
shared_ptr<int> sp2 = sp1;
cout << "引用计数:" << sp1.use_count() << endl;
*sp1 = 30;
cout << *sp2 << endl;
sp2.reset();
cout << "引用计数:" << sp1.use_count() << endl;
return 0;
}
4.weak_ptr 弱引用智能指针
weak_ptr不用于"对象所有权", 专门配合shared_ptr使用
a.不会增加shared_ptr的引用计数
b.解决shared_ptr的循环引用问题("循环引用会导致引用计数无法归0, 内存泄漏")
c.不能直接解引用, 需通过lock方法转换为shared_ptr后才能访问对象("同时检查对象是否还存在")
shared_ptr释放内存的条件是: "引用计数减至0"(所有指向该对象的shared_ptr都被销毁/重置), 而循环引用会让这个条件
永远无法满足 —— 即使外部的shared_ptr都销毁了, 对象内部互相持有的shared_ptr仍会让各自的引用计数保持 ≥1
#include <iostream>
#include <memory>
using namespace std;
class A;
class B;
class A {
public:
shared_ptr<B> b_ptr;
~A() { cout << "A析构(内存释放)" << endl; }
};
class B {
public:
shared_ptr<A> a_ptr;
~B() { cout << "B析构(内存释放)" << endl; }
};
int main() {
{
shared_ptr<A> a = make_shared<A>();
shared_ptr<B> b = make_shared<B>();
a->b_ptr = b;
b->a_ptr = a;
cout << "A的引用计数:" << a.use_count() << endl;
cout << "B的引用计数:" << b.use_count() << endl;
}
cout << "作用域结束,检查是否析构" << endl;
return 0;
}
#include <iostream>
#include <memory>
using namespace std;
class A;
class B;
class A {
public:
shared_ptr<B> b_ptr;
~A() { cout << "A被销毁(内存释放)" << endl; }
};
class B {
public:
weak_ptr<A> a_ptr;
~B() { cout << "B被销毁(内存释放)" << endl; }
};
int main() {
shared_ptr<A> a = make_shared<A>();
shared_ptr<B> b = make_shared<B>();
a->b_ptr = b;
b->a_ptr = a;
cout << "a的引用计数:" << a.use_count() << endl;
cout << "b的引用计数:" << b.use_count() << endl;
if (shared_ptr<A> temp = b->a_ptr.lock()) {
cout << "成功访问A对象" << endl;
} else {
cout << "A对象已销毁" << endl;
}
return 0;
}