[Effective C++]条款13:以对象管理资源

资源使用原则: 不论哪一种资源,重要的是当你不再使用它时,必须将它返给系统

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 
#include 

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

思维导图笔记
[Effective C++]条款13:以对象管理资源_第1张图片

你可能感兴趣的:(CPP,c++,开发语言)