【C++】智能指针


C++智能指针是一种自动管理动态内存的工具,通过RAII(资源获取即初始化)机制防止内存泄漏。以下是主要类型及示例:


一、智能指针的作用

  • 自动释放内存:避免因忘记delete导致内存泄漏。
  • 所有权管理:明确资源的所有权归属(独占或共享)。
  • 异常安全:在代码异常时仍能正确释放内存。

二、unique_ptr:独占所有权

  • 特点:同一时间只能有一个unique_ptr拥有对象,不可复制,但可通过std::move转移所有权。
  • 适用场景:明确资源唯一所有者的场景(如工厂模式返回对象)。
示例代码
#include <memory>
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "MyClass 构造\n"; }
    ~MyClass() { std::cout << "MyClass 析构\n"; }
    void print() { std::cout << "Hello from MyClass\n"; }
};

int main() {
    std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>();  // 创建
    ptr1->print();

    // 转移所有权给 ptr2
    std::unique_ptr<MyClass> ptr2 = std::move(ptr1);
    if (!ptr1) {
        std::cout << "ptr1 已释放所有权\n";
    }
    ptr2->print();
    return 0;
}

输出结果

MyClass 构造
Hello from MyClass
ptr1 已释放所有权
Hello from MyClass
MyClass 析构

三、shared_ptr:共享所有权

  • 特点:通过引用计数管理资源,多个指针共享同一对象,计数为0时释放内存。
  • 适用场景:需要多个对象共享同一资源的场景(如多线程缓存)。
示例代码
#include <memory>
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "MyClass 构造\n"; }
    ~MyClass() { std::cout << "MyClass 析构\n"; }
};

int main() {
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    {
        std::shared_ptr<MyClass> ptr2 = ptr1;  // 引用计数+1(总计数=2)
        std::cout << "内部作用域,计数: " << ptr1.use_count() << "\n";
    }  // ptr2 析构,计数-1(总计数=1)
    std::cout << "外部作用域,计数: " << ptr1.use_count() << "\n";
    return 0;
}

输出结果

MyClass 构造
内部作用域,计数: 2
外部作用域,计数: 1
MyClass 析构

四、weak_ptr:解决循环引用

  • 特点:观察但不拥有资源,不增加引用计数,需通过lock()转为shared_ptr使用。
  • 适用场景:打破shared_ptr循环引用(如双向链表、观察者模式)。
循环引用示例与解决
#include <memory>
#include <iostream>

class B;  // 前向声明

class A {
public:
    std::shared_ptr<B> b_ptr;
    ~A() { std::cout << "A 析构\n"; }
};

class B {
public:
    // std::shared_ptr<A> a_ptr;  // 导致循环引用
    std::weak_ptr<A> a_ptr;        // 使用 weak_ptr 解决
    ~B() { std::cout << "B 析构\n"; }
};

int main() {
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();
    a->b_ptr = b;
    b->a_ptr = a;  // weak_ptr 不增加引用计数
    return 0;
}

输出结果

A 析构
B 析构

五、注意事项

  1. 弃用auto_ptr:C++11起废弃,用unique_ptr替代。
  2. 优先使用make_shared/make_unique:更高效且避免内存泄漏(C++14支持make_unique)。
  3. 避免裸指针与智能指针混用:可能引发重复释放。
  4. 循环引用:必须用weak_ptr打破。

六、总结

  • unique_ptr:独占资源,性能最优。
  • shared_ptr:共享资源,注意循环引用。
  • weak_ptr:配合shared_ptr解决循环问题。

智能指针能显著提升代码安全性和可维护性,是现代C++内存管理的核心工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值