编辑代码

#include <iostream>
using namespace std;
#include<memory>
#include<functional>
// 1. 初始化
// std::unique_ptr 是一个独占型的智能指针,它不允许其他的智能指针共享其内部的指针,可以通过它的构造函数初始化一个独占智能指针对象,但是不允许通过赋值将一个 unique_ptr 赋值给另一个 unique_ptr。


// // 通过构造函数初始化对象
// unique_ptr<int> ptr1(new int(10));
// // error, 不允许将一个unique_ptr赋值给另一个unique_ptr
// unique_ptr<int> ptr2 = ptr1;
// std::unique_ptr 不允许复制,但是可以通过函数返回给其他的 std::unique_ptr,还可以通过 std::move 来转译给其他的 std::unique_ptr,这样原始指针的所有权就被转移了,这个原始指针还是被独占的。

unique_ptr<int> func()
{
    return unique_ptr<int>(new int(520));
}
void test()
{
    //通过构造函数初始化
    unique_ptr<int> ptr1(new int(10));
    //通过转移所有权的方式初始化
    unique_ptr<int> ptr2=move(ptr1);
    unique_ptr<int> ptr3=func();
    //unique_ptr 独占智能指针类也有一个reset方法,函数原型如下;
    
    unique_ptr<int> ptr4(new int(10));
    unique_ptr<int> ptr5=move(ptr4);
    ptr4.reset();
    ptr5.reset(new int(250));
    
    //同样是通过get方法来获取原始地址
    cout<<*ptr5.get()<<endl;
}

//2删除器
//unique_str 指定删除器和shared_ptr指定删除器是有区别的,unique_ptr指定删除器的时候需要确定删除器的类型,所以不能像
//shared_ptr那样直接指定删除器,举例说明。
void test2()
{
    shared_ptr<int>ptr1(new int(10),[](int *p){delete p;});//ok
    //unique_ptr<int>ptr2(new int(10),[](int *p){delete p;}); //err
    using func_ptr=void(*)(int*);
    unique_ptr<int,func_ptr> ptr3(new int(10),[](int *p){delete p;});

    //上面的44行代码,func_ptr的类型和lambda表达式的类型是一致的。在lambda表达式没有捕获任何变量的情况下是正确的,
    //如果捕获了变量,编译时则会报错;
    //unique_ptr<int,func_ptr> ptr4(new int(10),[&](int *p){delete p;});

    //上面的代码中错误原因是这样的,在 lambda 表达式没有捕获任何外部变量时,可以直接转换为函数指针,一旦捕获了就无法转换了,如果想要让编译器成功通过编译,那么需要使用可调用对象包装器来处理声明的函数指针:

    unique_ptr<int,function<void(int *)>> ptr5(new int(10),[&](int *p){delete p;});

}


int main() {
    test();
	return 0;
}