独占智能指针

发布时间 2023-12-12 15:07:02作者: Beasts777

文章参考:

爱编程的大丙 (subingwen.cn)

1. 初始化:

特点:

相较于共享智能指针,独占智能指针(unique_ptr)的关键在于:同一时刻,只能有一个智能指针指向同一块内存。因此独占智能指针不允许使用拷贝构造函数和拷贝赋值函数。

初始化:

  • 通过构造函数初始化:

    unique_ptr<int> ptr1(new int(100));
    
  • 通过移动构造函数/移动赋值函数:

    unique_ptr<int> ptr1(new int(100));
    unique_ptr<int> ptr2(move(ptr1));
    unique_ptr<int> ptr3 = move(ptr1);
    
  • 通过函数返回给其他的std::unique_ptr(本质上是返回一个右值,然后通过移动构造函数/移动赋值函数进行初始化):

    unique_ptr<int> func(){
        return unique_ptr<int>(new int(100));
    }
    int main(void){
        unique_ptr<int> ptr = func();
        return 0;
    }
    

2. 成员函数

2.1 reset

原型:

void reset( pointer ptr = pointer() ) noexcepter;

作用:

  • 解除独占智能指针对于目标内存的管理:

    unique_ptr<int> ptr1(new int(100));
    ptr1.reset();
    
  • 重新指定独占智能指针的目标内存:

    unique_ptr<int> ptr1(new int(100));
    ptr1.reset(new int(100));
    

2.2 get()

原型:

pointer get() const noexcept;

作用:

获取独占智能指针管理的原始地址。

3. 删除器

3.1 删除器类型

unique_ptr在指定删除器时和shared_ptr不同,unique_ptr必须指定删除器的类型,这就带来了一个问题:如果我们使用lambda表达式定义删除器,lambda表达式有以下特性:

  • 当lambda不捕获外部变量时,可以转化为一个函数指针。

    using func_ptr = void(*)(int*);
    unique_ptr<int, func_ptr> ptr(new int(100),
                                 [](int* p){
                                     delete p;
                                 });
    
  • 如果lambda捕获外部变量,那么就相当于一个仿函数。因此下面的代码存在错误:

    using func_ptr = void(*)(int*);
    // error。lambda捕获了外部变量的值,此时相当于一个仿函数,与函数指针不匹配。
    /* unique_ptr<int, func_ptr> ptr(new int(100),
                                 [&](int* p){
                                     delete p;
                                 }); */
    

因此,我们一般使用可调用对象包装器来指定独占智能指针的删除器类型:

unique_ptr<int, function<void(int*)>> ptr(new int(100),
                             [](int* p){
                                 delete p;
                             });

3.2 数组删除器

shared_ptr的操作一致。