Jupyter AI

7 智能指针之 unique_ptr 的使用

📅发表日期: 2024-08-10

🏷️分类: Cplus进阶

👁️阅读次数: 0

在上一篇文章中,我们深入探讨了 C++ 中的移动语义与完美转发,特别是移动构造与移动赋值操作。而在这一篇中,我们将专注于 C++11 引入的智能指针之一:unique_ptrunique_ptr 是一种用来管理动态分配内存的智能指针,它可以自动管理资源的生命周期,从而避免内存泄露。

什么是 unique_ptr

unique_ptr 是一种独占所有权的智能指针。它所指向的对象只能由一个 unique_ptr 拥有,不能被复制,但可以通过移动操作来转移所有权。这使得 unique_ptr 成为资源管理的安全方式。

unique_ptr 的基本使用

下面,我们来看一下 unique_ptr 的基本用法。

创建 unique_ptr

使用 std::make_unique 创建 unique_ptr 是一种推荐的方式:

#include <iostream>
#include <memory>

class Example {
public:
    Example() { std::cout << "Example created\n"; }
    ~Example() { std::cout << "Example destroyed\n"; }
    void show() { std::cout << "Showing Example\n"; }
};

int main() {
    // 创建 unique_ptr
    std::unique_ptr<Example> ptr = std::make_unique<Example>();
    ptr->show();
    
    // ptr 超出作用域时,Example 会被自动销毁
    return 0;
}

在这个示例中,我们使用 std::make_unique<Example>() 来创建 unique_ptr。当 ptr 超出作用域时,Example 对象会被自动销毁,避免了手动调用 delete 的麻烦。

移动 unique_ptr

由于 unique_ptr 的所有权是独占的,无法复制,但可以通过移动来转移所有权。

#include <iostream>
#include <memory>

class Example {
public:
    Example() { std::cout << "Example created\n"; }
    ~Example() { std::cout << "Example destroyed\n"; }
};

int main() {
    std::unique_ptr<Example> ptr1 = std::make_unique<Example>();

    // 移动 ptr1 到 ptr2
    std::unique_ptr<Example> ptr2 = std::move(ptr1);
    
    if (!ptr1) {
        std::cout << "ptr1 is now empty\n";
    }
    
    // ptr2 现在拥有 Example 的所有权
    return 0;
}

在这个示例中,std::move(ptr1) 被用于将 ptr1 的所有权转移到 ptr2。一旦移动后,ptr1 将变为 nullptr,因此可以在后续代码中检查它的状态。

自定义删除器

unique_ptr 还允许我们自定义删除器,这在处理资源时非常有用。

#include <iostream>
#include <memory>

void customDeleter(Example* e) {
    std::cout << "Custom deleting Example\n";
    delete e;
}

int main() {
    std::unique_ptr<Example, decltype(&customDeleter)> ptr(new Example(), customDeleter);
    return 0;
}

在上面的代码中,我们定义了一个自定义删除器 customDeleter,并使用 decltype 指定了 unique_ptr 的删除器类型。当 ptr 超出作用域时,将调用自定义删除器来释放内存。

注意事项

  1. 不可复制unique_ptr 不能被复制,必须使用 std::move 来转移所有权。
  2. 避免循环引用:在使用 unique_ptr 的时候要注意,如果两个对象相互持有 unique_ptr,将导致内存泄露。
  3. 适用于动态分配的资源unique_ptr 主要用于管理动态分配的资源。

小结

在这一篇中,我们详细地探讨了 C++ 中的 unique_ptr,并且通过多个示例展示了它的创建、移动和自定义删除器的使用。unique_ptr 的引入大大简化了内存管理,让我们可以更安全地管理动态分配的资源。

接下来的篇章中,我们将继续介绍其他智能指针,包括 shared_ptrweak_ptr,并比较它们各自的用途与特点。希望大家能继续关注学习。

💬 评论

暂无评论