C++中的智能指针的种类,和普通指针的区别

发布于:2024-06-26 ⋅ 阅读:(20) ⋅ 点赞:(0)

智能指针

C++ 中的智能指针(Smart Pointers)是用于自动管理动态分配内存的指针。它们与普通指针(raw pointers)不同,智能指针自动管理内存的生命周期,以避免内存泄漏和悬挂指针等问题。C++ 标准库提供了几种常用的智能指针:

  1. std::unique_ptr
  2. std::shared_ptr
  3. std::weak_ptr

std::unique_ptr

特点
  • 独占所有权:每个 unique_ptr 对象独占其管理的资源,不能共享所有权。
  • 不可复制:unique_ptr 不允许复制,但可以移动。
  • 自动释放:当 unique_ptr 离开作用域时,自动释放所管理的资源。
示例
#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "MyClass Constructor" << std::endl; }
    ~MyClass() { std::cout << "MyClass Destructor" << std::endl; }
};

int main() {
    std::unique_ptr<MyClass> ptr1(new MyClass());  // 创建一个 unique_ptr
    // std::unique_ptr<MyClass> ptr2 = ptr1;       // 错误:unique_ptr 不可复制
    std::unique_ptr<MyClass> ptr2 = std::move(ptr1); // 移动所有权
    return 0;  // 自动调用 MyClass 的析构函数
}

std::shared_ptr

特点
  • 共享所有权:多个 shared_ptr 可以共享同一个资源,使用引用计数来管理资源的生命周期。
  • 自动释放:当最后一个 shared_ptr 离开作用域时,自动释放所管理的资源。
示例
#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "MyClass Constructor" << std::endl; }
    ~MyClass() { std::cout << "MyClass Destructor" << std::endl; }
};

int main() {
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();  // 创建一个 shared_ptr
    {
        std::shared_ptr<MyClass> ptr2 = ptr1;  // 共享所有权
        std::cout << "ptr2's use count: " << ptr2.use_count() << std::endl;  // 输出 2
    }  // ptr2 离开作用域,不销毁资源
    std::cout << "ptr1's use count: " << ptr1.use_count() << std::endl;  // 输出 1
    return 0;  // 自动调用 MyClass 的析构函数
}

std::weak_ptr

特点
  • 弱引用:weak_ptr 不增加资源的引用计数,主要用于打破 shared_ptr 之间的循环引用。
  • 配合 shared_ptr 使用:weak_ptr 不能独立管理资源,必须从一个 shared_ptr 创建。
示例
#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "MyClass Constructor" << std::endl; }
    ~MyClass() { std::cout << "MyClass Destructor" << std::endl; }
};

int main() {
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    std::weak_ptr<MyClass> weakPtr = ptr1;  // 创建一个 weak_ptr
    std::cout << "ptr1's use count: " << ptr1.use_count() << std::endl;  // 输出 1

    if (auto ptr2 = weakPtr.lock()) {  // 尝试锁定 weak_ptr 得到 shared_ptr
        std::cout << "Lock succeeded. ptr1's use count: " << ptr1.use_count() << std::endl;  // 输出 2
    } else {
        std::cout << "Lock failed." << std::endl;
    }

    return 0;  // 自动调用 MyClass 的析构函数
}

智能指针与普通指针的区别

  1. 内存管理

    • 智能指针:自动管理内存的生命周期,当不再使用时自动释放资源,避免内存泄漏。
    • 普通指针:需要手动管理内存的分配和释放,容易导致内存泄漏和悬挂指针。
  2. 所有权

    • 智能指针:可以明确所有权关系,unique_ptr 独占所有权,shared_ptr 共享所有权,weak_ptr 弱引用不持有所有权。
    • 普通指针:没有所有权概念,多个指针可以指向同一块内存,没有自动管理机制。
  3. 安全性

    • 智能指针:提供安全的资源管理,防止悬挂指针和重复释放。
    • 普通指针:容易导致悬挂指针、内存泄漏和重复释放。
  4. 性能

    • 智能指针:引入了少量的性能开销(如引用计数的维护)。
    • 普通指针:直接操作内存,没有额外开销,但需要更小心的管理。

总结

智能指针在 C++ 中提供了一种安全、方便的内存管理机制,帮助开发者避免常见的内存管理错误。根据具体需求,选择合适的智能指针类型可以有效提高代码的安全性和可维护性。