C++智能指针

智能指针是C++中用于自动管理动态分配内存的类模板,它们通过在适当的时机自动释放内存来帮助防止内存泄漏。C++11引入了以下几种主要的智能指针:

1. std::unique_ptr

独占所有权的智能指针,同一时间只能有一个unique_ptr指向特定对象。

#include 

void example_unique() {
    // 创建unique_ptr
    std::unique_ptr ptr1(new int(10));
    
    // 使用make_unique (C++14推荐)
    auto ptr2 = std::make_unique(20);
    
    // 转移所有权
    std::unique_ptr ptr3 = std::move(ptr1);  // ptr1现在为nullptr
    
    // 访问指针内容
    if(ptr3) {
        std::cout << *ptr3 << std::endl;  // 输出10
    }
    
    // 自动释放内存
}  // 退出作用域时自动删除

特点:

  • 不能复制,只能移动

  • 轻量级,几乎无额外开销

  • 可以自定义删除器

2. std::shared_ptr

共享所有权的智能指针,使用引用计数管理资源。

void example_shared() {
    // 创建shared_ptr
    std::shared_ptr ptr1(new int(30));
    
    // 使用make_shared (推荐)
    auto ptr2 = std::make_shared(40);
    
    // 复制shared_ptr
    auto ptr3 = ptr2;  // 引用计数增加
    
    // 查看引用计数
    std::cout << ptr3.use_count() << std::endl;  // 输出2
    
    // 自动释放内存
}  // 当引用计数为0时删除对象

特点:

  • 可以复制,引用计数增加

  • 有少量额外开销(引用计数和控制块)

  • 可能产生循环引用问题

3. std::weak_ptr

弱引用智能指针,不增加引用计数,用于解决shared_ptr循环引用问题。

void example_weak() {
    auto shared = std::make_shared(50);
    std::weak_ptr weak = shared;
    
    // 使用前需要转换为shared_ptr
    if(auto temp = weak.lock()) {
        std::cout << *temp << std::endl;  // 输出50
    }
    
    shared.reset();  // 删除对象
    
    if(weak.expired()) {
        std::cout << "Object has been deleted" << std::endl;
    }
}

特点:

  • 不拥有对象所有权

  • 不会阻止对象被释放

  • 常用于观察者模式或缓存实现

4. 智能指针的选择

  • 优先使用unique_ptr:默认选择,除非需要共享所有权

  • 需要共享所有权时使用shared_ptr

  • 需要观察但不拥有对象时使用weak_ptr

  • 避免裸指针,除非与旧代码交互必须使用

5. 自定义删除器

智能指针允许自定义删除行为:

void custom_deleter(int* p) {
    std::cout << "Custom delete\n";
    delete p;
}

void example_custom_deleter() {
    // unique_ptr 自定义删除器
    std::unique_ptr ptr1(new int(60), custom_deleter);
    
    // shared_ptr 自定义删除器
    std::shared_ptr ptr2(new int(70), [](int* p) {
        std::cout << "Lambda delete\n";
        delete p;
    });
}

6. 注意事项

  • 不要混合使用智能指针和裸指针

  • 避免循环引用(使用weak_ptr解决)

  • 优先使用make_sharedmake_unique(更安全、更高效)

  • 不要对同一块内存使用多个独立的智能指针

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