std::shared_ptr和unique_ptr
时间: 2023-10-21 13:31:23 浏览: 89
是什么?它们之间有什么区别?
std::shared_ptr和std::unique_ptr都是C++11的智能指针,用于管理动态分配的对象。它们的主要区别在于指针所有权的控制方式。
std::shared_ptr使用引用计数方式,可以有多个指针共享同一个对象,并且会在最后一个指针释放时自动销毁对象。这种方式适用于共享一个对象的场景。但是引用计数方式也会带来一些额外的开销,比如线程安全的引用计数机制和动态内存分配。
std::unique_ptr则采用独占式所有权,即只能有一个指针拥有该对象的所有权,不允许多个指针共享一个对象。当拥有对象的指针被销毁时,该对象也会被自动销毁。这种方式适用于单一所有权场景,可以避免引用计数机制带来的开销。同时,使用std::unique_ptr还可以通过移动语义和非拥有性指针传递实现更高效的内存管理。
相关问题
std::weak_ptr std::unique_ptr std::shared_ptr区别
这三个指针是 C++11 中引入的智能指针,它们的主要区别在于对于对象的所有权控制和内存管理方式的不同。
1. `unique_ptr` 是独占所有权智能指针,它不能被复制,只能通过移动(move)转移所有权。因此,使用 `unique_ptr` 可以确保在任何时刻只有一个指针可以访问该对象,当它被销毁时,它所指向的对象也会被销毁。适用于需要严格的资源管理和内存安全保证的场景。
2. `shared_ptr` 是共享所有权智能指针,它可以被多个指针共享,每个指针都有一个计数器来记录有多少个指针指向该对象,当计数器为 0 时,对象会被销毁。它使用引用计数的方式管理内存,适用于需要多个指针共享同一资源的场景。
3. `weak_ptr` 是一种不控制对象生命周期的智能指针,它可以被赋值为一个 `shared_ptr`,但不会增加对象的引用计数,当 `shared_ptr` 被销毁后,`weak_ptr` 仍然可以访问对象,但是它的 `lock()` 成员函数将返回一个空指针(`nullptr`)。`weak_ptr` 适用于需要引用 `shared_ptr` 所管理的对象,但又不需要控制对象生命周期的场景。
总之,`unique_ptr` 是独占所有权的智能指针,`shared_ptr` 是共享所有权的智能指针,而 `weak_ptr` 则是一种不控制对象生命周期的智能指针。
std::shared_ptr to std::unique_ptr
转换一个 `std::shared_ptr` 到 `std::unique_ptr` 是有可能的,但是需要注意以下几点:
1. `std::unique_ptr` 拥有对象的所有权,而 `std::shared_ptr` 则是多个所有者共享一个对象的所有权,因此在转换时需要确保 `std::shared_ptr` 的引用计数为1,否则转换后的 `std::unique_ptr` 会在析构时删除对象,导致其他 `std::shared_ptr` 失效。
2. 转换时需要指定删除器,否则会使用默认删除器,可能导致不正确的对象删除行为。
下面是一个示例代码:
```
std::shared_ptr<int> shared = std::make_shared<int>(42);
std::unique_ptr<int, std::function<void(int*)>> unique(shared.get(), [](int* ptr) { delete ptr; });
shared.release();
```
在这个示例中,我们首先创建了一个 `std::shared_ptr<int>`,然后用 `shared.get()` 获取了指向对象的指针,并将其传递给了 `std::unique_ptr<int>` 的构造函数中。同时,我们也提供了一个删除器 `std::function<void(int*)>`,用于在析构时正确删除对象。最后,我们通过 `shared.release()` 释放了 `std::shared_ptr` 对对象的所有权,此时 `std::unique_ptr` 就拥有了对象的所有权。
需要注意的是,这种转换并不是推荐的做法,因为它容易引起对象所有权的混乱和不确定性。因此,在使用 `std::unique_ptr` 和 `std::shared_ptr` 时应该遵循它们的使用规范,避免不必要的转换。
阅读全文