资源使用原则: 不论哪一种资源,重要的是当你不再使用它时,必须将它返给系统
1、通过动态内存分配的资源,在使用过程中可能发生的问题
1.1、内存泄漏
- 如果手动分配内存(如使用new)后忘记调用delete,会导致内存泄漏
- 每次调用foo函数都会泄漏一块内存,这快资源无法回收,也不可再使用
void foo() {
int* p = new int(10);
// 忘记 delete p;
}
1.2、悬空指针
- 已被释放的指针,任然被使用,会导致未定义行为
int* p = new int(10);
delete p;
*p = 20; // 悬空指针,未定义行为
1.3、双重释放
- 同一块内存释放两次,会导致程序崩溃
int* p = new int(10);
delete p;
delete p; // 双重释放,程序崩溃
1.4、运行过程中发生异常,导致没有进行资源释放
- 在new和delete之间发生异常,导致内存泄漏
void foo() {
int* p = new int(10);
throw std::runtime_error("Error");
delete p; // 永远不会执行
}
2、适合使用智能指针的场景
2.1、动态内存管理
- 当需要动态分配内存时,使用智能指针可以自动管理内存生命周期
- 智能指针能够在获得资源后立刻放到管理对象中,当离开foo函数时,指针指针对象会在析构函数中自动释放管理的对象资源
void foo(){
std::unique_ptr<MyClass> p = std::make_unique<MyClass>(new MyClass());
...
}
2.2、工厂函数返回对象
- 工厂函数返回动态分配的对象时,使用智能指针可以避免手动管理内存
std::unique_ptr<MyClass> createObject() {
return std::make_unique<MyClass>();
}
2.3、共享所有权
- 当多个对象需要共享同一块内存时,使用std::shared_ptr
std::shared_ptr<MyClass> obj1 = std::make_shared<MyClass>();
std::shared_ptr<MyClass> obj2 = obj1; // 共享所有权
3、C++标准库中提供的三类智能指针类型
3.1、std::unique_ptr
- 独占所有权,不能复制,智能移动,适用于单一所有权的场景
std::unique_ptr<int> p = std::make_unique<int>(10);
std::unique_ptr<int> p2 = std::move(p); // 所有权转移
3.2、std::shared_ptr
- 共享所有权,使用引用计数管理内存,适用于多个对象共享同一块内存的场景
std::shared_ptr<int> p1 = std::make_shared<int>(10);
std::shared_ptr<int> p2 = p1; // 共享所有权
3.3、std::weak_ptr
- 弱引用,不增加引用计数,用于打破std::shared_ptr的循环引用
std::shared_ptr<int> p1 = std::make_shared<int>(10);
std::weak_ptr<int> p2 = p1; // 弱引用
例子:
- 调用者无需手动管理内存,对象在离开作用域时自动释放资源
#include <iostream>
#include <memory>
class MyClass {
public:
MyClass() { std::cout << "MyClass created\n"; }
~MyClass() { std::cout << "MyClass destroyed\n"; }
void doSomething() { std::cout << "Doing something\n"; }
};
// 工厂函数返回 unique_ptr
std::unique_ptr<MyClass> createObject() {
return std::make_unique<MyClass>();
}
int main() {
{
std::unique_ptr<MyClass> obj = createObject();
obj->doSomething();
// obj 离开作用域时自动释放内存
}
std::cout << "Object destroyed automatically\n";
return 0;
}
输出:
MyClass created
Doing something
MyClass destroyed
Object destroyed automatically
思维导图笔记