C++ unique_ptr
时间: 2023-12-19 18:05:45 浏览: 89
C++11中的unique_ptr是一种智能指针,它提供了一种独占式拥有其所指向对象的所有权的语义,即同一时间内只能有一个unique_ptr指向一个对象。当unique_ptr被销毁时,它所指向的对象也会被销毁。unique_ptr的使用可以避免内存泄漏和悬空指针等问题。
以下是unique_ptr的基本使用方法:
1. 创建unique_ptr对象
```c++
std::unique_ptr<int> p(new int(10)); // 创建一个指向int类型对象的unique_ptr
```
2. 获取unique_ptr指向的对象
```c++
int a = *p; // 获取unique_ptr指向的对象的值
```
3. 释放unique_ptr指向的对象
```c++
p.reset(); // 释放unique_ptr指向的对象
```
4. 将unique_ptr转移给其他unique_ptr
```c++
std::unique_ptr<int> p1 = std::move(p); // 将p指向的对象的所有权转移给p1
```
需要注意的是,由于unique_ptr的独占性质,不能将一个unique_ptr赋值给另一个unique_ptr或者将一个unique_ptr作为参数传递给一个函数,除非使用std::move进行转移。
相关问题
c++ unique_ptr
### C++ `unique_ptr` 使用方法及示例
#### 创建和初始化 `unique_ptr`
`std::unique_ptr` 是一种独占所有权的智能指针,意味着同一时间只有一个 `unique_ptr` 实例拥有该资源。创建 `unique_ptr` 的方式有多种:
```cpp
#include <iostream>
#include <memory>
using namespace std;
void demonstrate_unique_ptr_creation() {
// 方法一:通过 make_unique 函数 (推荐)
auto ptr1 = make_unique<int>(42);
// 方法二:直接调用构造函数
unique_ptr<int> ptr2(new int(84));
cout << "Value of ptr1: " << *ptr1 << endl;
cout << "Value of ptr2: " << *ptr2 << endl;
}
```
#### 返回 `unique_ptr` 作为函数返回值
由于 `unique_ptr` 支持移动语义而非拷贝语义,因此可以直接从函数中返回它而无需担心深浅拷贝问题。
```cpp
unique_ptr<int> create_and_return_unique_ptr(int value) {
return make_unique<int>(value);
}
void use_function_to_create_unique_ptr() {
unique_ptr<int> returnedPtr = create_and_return_unique_ptr(99);
cout << "Returned unique_ptr points to: " << *returnedPtr << endl;
}
```
#### 将 `unique_ptr` 存储于标准库容器内
当需要存储动态分配的对象集合时,可以考虑使用包含 `unique_ptr` 的 STL 容器来管理这些对象的生命期。
```cpp
void store_in_container() {
vector<unique_ptr<string>> stringPointers;
// 添加新元素到向量中
stringPointers.push_back(make_unique<string>("Hello"));
stringPointers.emplace_back(new string("World"));
for(auto& p : stringPointers){
cout << *p << ' ';
}
cout << endl;
}
```
以上展示了如何利用 `make_unique`, 构造函数以及将其用于函数返回值和容器成员等方面的操作[^1]。
C++ unique_ptr底层
### C++ `unique_ptr` 的底层实现机制
#### 类模板定义
`std::unique_ptr` 是一个类模板,用于表示独占所有权的智能指针。其基本结构如下:
```cpp
template<class T, class Deleter = std::default_delete<T>>
class unique_ptr {
private:
pointer ptr_; // 存储实际的对象指针
public:
using pointer = typename remove_reference<T>::type*;
constexpr unique_ptr() noexcept : ptr_(nullptr) {}
explicit unique_ptr(pointer p) noexcept : ptr_(p) {}
~unique_ptr() { reset(); }
void reset(pointer p = pointer()) noexcept {
if (ptr_ != p) {
if (ptr_) get_deleter()(ptr_);
ptr_ = p;
}
}
pointer release() noexcept {
pointer old_ptr = ptr_;
ptr_ = nullptr;
return old_ptr;
}
pointer get() const noexcept { return ptr_; }
};
```
这段代码展示了 `unique_ptr` 如何存储指向对象的裸指针并提供一些基础操作方法[^1]。
#### 构造与销毁
当创建一个新的 `unique_ptr` 实例时,可以传入一个原始指针给构造函数来初始化内部成员变量 `ptr_` 。而一旦超出作用域或显式调用了析构函数,则会自动释放所持有的资源,并确保不会发生双重删除等问题。
对于自定义删除器的情况,`unique_ptr` 支持传递第二个参数作为删除策略,默认情况下使用的是标准库提供的 `std::default_delete` ,它可以处理任意类型的动态分配内存[^3]。
#### 所有权转移
不同于共享型智能指针如 `shared_ptr` 可能引发循环引用问题[^2],`unique_ptr` 设计之初就强调单一持有者概念——即同一时间只能有一个 `unique_ptr` 对象拥有某个特定资源的所有权。因此,在赋值运算符重载以及移动语义的支持下实现了高效且安全的所有权转让方式而不涉及深拷贝开销。
- **Move Semantics**: 当执行右值引用绑定(`&&`) 或者 move assignment (`operator=`),原实例失去对其控制并将数据交给目标实例接管;此时源端会被置为空(null)状态以防止误用。
```cpp
// Move constructor example
unique_ptr<int> uptr(new int(42));
unique_ptr<int> moved_uptr(std::move(uptr)); // After this line, 'uptr' becomes null.
```
这种设计使得 `unique_ptr` 成为了现代C++编程中最轻量级也是最推荐使用的智能指针之一[^4]。
阅读全文
相关推荐













